blob: e8e5800096efc873368bc3c567e1e5006b6ec5d1 [file] [log] [blame]
Ramon Fried914026d2019-04-27 11:15:21 +03001/* SPDX-License-Identifier: GPL-2.0+ */
2/*
3 * Adapted from Linux kernel driver
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * (C) Copyright 2019
8 * Ramon Fried <ramon.fried@gmail.com>
9 */
10
11#ifndef _PCI_EP_H
12#define _PCI_EP_H
13
14#include <pci.h>
15
16/**
17 * enum pci_interrupt_pin - PCI INTx interrupt values
18 * @PCI_INTERRUPT_UNKNOWN: Unknown or unassigned interrupt
19 * @PCI_INTERRUPT_INTA: PCI INTA pin
20 * @PCI_INTERRUPT_INTB: PCI INTB pin
21 * @PCI_INTERRUPT_INTC: PCI INTC pin
22 * @PCI_INTERRUPT_INTD: PCI INTD pin
23 *
24 * Corresponds to values for legacy PCI INTx interrupts, as can be found in the
25 * PCI_INTERRUPT_PIN register.
26 */
27enum pci_interrupt_pin {
28 PCI_INTERRUPT_UNKNOWN,
29 PCI_INTERRUPT_INTA,
30 PCI_INTERRUPT_INTB,
31 PCI_INTERRUPT_INTC,
32 PCI_INTERRUPT_INTD,
33};
34
35enum pci_barno {
36 BAR_0,
37 BAR_1,
38 BAR_2,
39 BAR_3,
40 BAR_4,
41 BAR_5,
42};
43
44enum pci_ep_irq_type {
45 PCI_EP_IRQ_UNKNOWN,
46 PCI_EP_IRQ_LEGACY,
47 PCI_EP_IRQ_MSI,
48 PCI_EP_IRQ_MSIX,
49};
50
51/**
52 * struct pci_bar - represents the BAR (Base Address Register) of EP device
53 * @phys_addr: physical address that should be mapped to the BAR
54 * @size: the size of the address space present in BAR
55 * pci_barno: number of pci BAR to set (0..5)
56 * @flags: BAR access flags
57 */
58struct pci_bar {
59 dma_addr_t phys_addr;
60 size_t size;
61 enum pci_barno barno;
62 int flags;
63};
64
65/**
66 * struct pci_ep_header - represents standard configuration header
67 * @vendorid: identifies device manufacturer
68 * @deviceid: identifies a particular device
69 * @revid: specifies a device-specific revision identifier
70 * @progif_code: identifies a specific register-level programming interface
71 * @subclass_code: identifies more specifically the function of the device
72 * @baseclass_code: broadly classifies the type of function the device performs
73 * @cache_line_size: specifies the system cacheline size in units of DWORDs
74 * @subsys_vendor_id: vendor of the add-in card or subsystem
75 * @subsys_id: id specific to vendor
76 * @interrupt_pin: interrupt pin the device (or device function) uses
77 */
78struct pci_ep_header {
79 u16 vendorid;
80 u16 deviceid;
81 u8 revid;
82 u8 progif_code;
83 u8 subclass_code;
84 u8 baseclass_code;
85 u8 cache_line_size;
86 u16 subsys_vendor_id;
87 u16 subsys_id;
88 enum pci_interrupt_pin interrupt_pin;
89};
90
91/* PCI endpoint operations */
92struct pci_ep_ops {
93 /**
94 * write_header() - Write a PCI configuration space header
95 *
96 * @dev: device to write to
97 * @func_num: EP function to fill
98 * @hdr: header to write
99 * @return 0 if OK, -ve on error
100 */
101 int (*write_header)(struct udevice *dev, uint func_num,
102 struct pci_ep_header *hdr);
103 /**
104 * read_header() - Read a PCI configuration space header
105 *
106 * @dev: device to write to
107 * @func_num: EP function to fill
108 * @hdr: header to read to
109 * @return 0 if OK, -ve on error
110 */
111 int (*read_header)(struct udevice *dev, uint func_num,
112 struct pci_ep_header *hdr);
113 /**
114 * set_bar() - Set BAR (Base Address Register) properties
115 *
116 * @dev: device to set
117 * @func_num: EP function to set
118 * @bar: bar data
119 * @return 0 if OK, -ve on error
120 */
121 int (*set_bar)(struct udevice *dev, uint func_num,
122 struct pci_bar *bar);
123 /**
124 * read_bar() - Read BAR (Base Address Register) properties
125 *
126 * @dev: device to read
127 * @func_num: EP function to read
128 * @bar: struct to copy data to
129 * @barno: bar number to read
130 * @return 0 if OK, -ve on error
131 */
132 int (*read_bar)(struct udevice *dev, uint func_num,
133 struct pci_bar *bar, enum pci_barno barno);
134 /**
135 * clear_bar() - clear BAR (Base Address Register)
136 *
137 * @dev: device to clear
138 * @func_num: EP function to clear
139 * @bar: bar number
140 * @return 0 if OK, -ve on error
141 */
142 int (*clear_bar)(struct udevice *dev, uint func_num,
143 enum pci_barno bar);
144 /**
145 * map_addr() - map CPU address to PCI address
146 *
147 * outband region is used in order to generate PCI read/write
148 * transaction from local memory/write.
149 *
150 * @dev: device to set
151 * @func_num: EP function to set
152 * @addr: local physical address base
153 * @pci_addr: pci address to translate to
154 * @size: region size
155 * @return 0 if OK, -ve on error
156 */
157 int (*map_addr)(struct udevice *dev, uint func_num,
158 phys_addr_t addr, u64 pci_addr, size_t size);
159 /**
160 * unmap_addr() - unmap CPU address to PCI address
161 *
162 * unmap previously mapped region.
163 *
164 * @dev: device to set
165 * @func_num: EP function to set
166 * @addr: local physical address base
167 * @return 0 if OK, -ve on error
168 */
169 int (*unmap_addr)(struct udevice *dev, uint func_num,
170 phys_addr_t addr);
171 /**
172 * set_msi() - set msi capability property
173 *
174 * set the number of required MSI vectors the device
175 * needs for operation.
176 *
177 * @dev: device to set
178 * @func_num: EP function to set
179 * @interrupts: required interrupts count
180 * @return 0 if OK, -ve on error
181 */
182 int (*set_msi)(struct udevice *dev, uint func_num, uint interrupts);
183
184 /**
185 * get_msi() - get the number of MSI interrupts allocated by the host.
186 *
187 * Read the Multiple Message Enable bitfield from
188 * Message control register.
189 *
190 * @dev: device to use
191 * @func_num: EP function to use
192 * @return msi count if OK, -EINVAL if msi were not enabled at host.
193 */
194 int (*get_msi)(struct udevice *dev, uint func_num);
195
196 /**
197 * set_msix() - set msix capability property
198 *
199 * set the number of required MSIx vectors the device
200 * needs for operation.
201 *
202 * @dev: device to set
203 * @func_num: EP function to set
204 * @interrupts: required interrupts count
205 * @return 0 if OK, -ve on error
206 */
207 int (*set_msix)(struct udevice *dev, uint func_num,
208 uint interrupts);
209
210 /**
211 * get_msix() - get the number of MSIx interrupts allocated by the host.
212 *
213 * Read the Multiple Message Enable bitfield from
214 * Message control register.
215 *
216 * @dev: device to use
217 * @func_num: EP function to use
218 * @return msi count if OK, -EINVAL if msi were not enabled at host.
219 */
220 int (*get_msix)(struct udevice *dev, uint func_num);
221
222 /**
223 * raise_irq() - raise a legacy, MSI or MSI-X interrupt
224 *
225 * @dev: device to set
226 * @func_num: EP function to set
227 * @type: type of irq to send
228 * @interrupt_num: interrupt vector to use
229 * @return 0 if OK, -ve on error
230 */
231 int (*raise_irq)(struct udevice *dev, uint func_num,
232 enum pci_ep_irq_type type, uint interrupt_num);
233 /**
234 * start() - start the PCI link
235 *
236 * @dev: device to set
237 * @return 0 if OK, -ve on error
238 */
239 int (*start)(struct udevice *dev);
240
241 /**
242 * stop() - stop the PCI link
243 *
244 * @dev: device to set
245 * @return 0 if OK, -ve on error
246 */
247 int (*stop)(struct udevice *dev);
248};
249
250#define pci_ep_get_ops(dev) ((struct pci_ep_ops *)(dev)->driver->ops)
251
252/**
253 * pci_ep_write_header() - Write a PCI configuration space header
254 *
255 * @dev: device to write to
256 * @func_num: EP function to fill
257 * @hdr: header to write
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100258 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300259 */
260int pci_ep_write_header(struct udevice *dev, uint func_num,
261 struct pci_ep_header *hdr);
262
263/**
264 * dm_pci_ep_read_header() - Read a PCI configuration space header
265 *
266 * @dev: device to write to
267 * @func_num: EP function to fill
268 * @hdr: header to read to
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100269 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300270 */
271int pci_ep_read_header(struct udevice *dev, uint func_num,
272 struct pci_ep_header *hdr);
273/**
274 * pci_ep_set_bar() - Set BAR (Base Address Register) properties
275 *
276 * @dev: device to set
277 * @func_num: EP function to set
278 * @bar: bar data
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100279 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300280 */
281int pci_ep_set_bar(struct udevice *dev, uint func_num, struct pci_bar *bar);
282
283/**
284 * pci_ep_read_bar() - Read BAR (Base Address Register) properties
285 *
286 * @dev: device to read
287 * @func_num: EP function to read
288 * @bar: struct to copy data to
289 * @barno: bar number to read
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100290 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300291 */
292int pci_ep_read_bar(struct udevice *dev, uint func_no, struct pci_bar *ep_bar,
293 enum pci_barno barno);
294
295/**
296 * pci_ep_clear_bar() - Clear BAR (Base Address Register)
297 * mark the BAR as empty so host won't map it.
298 * @dev: device to clear
299 * @func_num: EP function to clear
300 * @bar: bar number
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100301 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300302 */
303int pci_ep_clear_bar(struct udevice *dev, uint func_num, enum pci_barno bar);
304/**
305 * pci_ep_map_addr() - map CPU address to PCI address
306 *
307 * outband region is used in order to generate PCI read/write
308 * transaction from local memory/write.
309 *
310 * @dev: device to set
311 * @func_num: EP function to set
312 * @addr: local physical address base
313 * @pci_addr: pci address to translate to
314 * @size: region size
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100315 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300316 */
317int pci_ep_map_addr(struct udevice *dev, uint func_num, phys_addr_t addr,
318 u64 pci_addr, size_t size);
319/**
320 * pci_ep_unmap_addr() - unmap CPU address to PCI address
321 *
322 * unmap previously mapped region.
323 *
324 * @dev: device to set
325 * @func_num: EP function to set
326 * @addr: local physical address base
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100327 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300328 */
329int pci_ep_unmap_addr(struct udevice *dev, uint func_num, phys_addr_t addr);
330
331/**
332 * pci_ep_set_msi() - set msi capability property
333 *
334 * set the number of required MSI vectors the device
335 * needs for operation.
336 *
337 * @dev: device to set
338 * @func_num: EP function to set
339 * @interrupts: required interrupts count
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100340 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300341 */
342int pci_ep_set_msi(struct udevice *dev, uint func_num, uint interrupts);
343
344/**
345 * pci_ep_get_msi() - get the number of MSI interrupts allocated by the host.
346 *
347 * Read the Multiple Message Enable bitfield from
348 * Message control register.
349 *
350 * @dev: device to use
351 * @func_num: EP function to use
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100352 * Return: msi count if OK, -EINVAL if msi were not enabled at host.
Ramon Fried914026d2019-04-27 11:15:21 +0300353 */
354int pci_ep_get_msi(struct udevice *dev, uint func_num);
355
356/**
357 * pci_ep_set_msix() - set msi capability property
358 *
359 * set the number of required MSIx vectors the device
360 * needs for operation.
361 *
362 * @dev: device to set
363 * @func_num: EP function to set
364 * @interrupts: required interrupts count
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100365 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300366 */
367int pci_ep_set_msix(struct udevice *dev, uint func_num, uint interrupts);
368
369/**
370 * pci_ep_get_msix() - get the number of MSIx interrupts allocated by the host.
371 *
372 * Read the Multiple Message Enable bitfield from
373 * Message control register.
374 *
375 * @dev: device to use
376 * @func_num: EP function to use
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100377 * Return: msi count if OK, -EINVAL if msi were not enabled at host.
Ramon Fried914026d2019-04-27 11:15:21 +0300378 */
379int pci_ep_get_msix(struct udevice *dev, uint func_num);
380
381/**
382 * pci_ep_raise_irq() - raise a legacy, MSI or MSI-X interrupt
383 *
384 * @dev: device to set
385 * @func_num: EP function to set
386 * @type: type of irq to send
387 * @interrupt_num: interrupt vector to use
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100388 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300389 */
390int pci_ep_raise_irq(struct udevice *dev, uint func_num,
391 enum pci_ep_irq_type type, uint interrupt_num);
392/**
393 * pci_ep_start() - start the PCI link
394 *
395 * Enable PCI endpoint device and start link
396 * process.
397 *
398 * @dev: device to set
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100399 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300400 */
401int pci_ep_start(struct udevice *dev);
402
403/**
404 * pci_ep_stop() - stop the PCI link
405 *
406 * Disable PCI endpoint device and stop
407 * link.
408 *
409 * @dev: device to set
Heinrich Schuchardt185f8122022-01-19 18:05:50 +0100410 * Return: 0 if OK, -ve on error
Ramon Fried914026d2019-04-27 11:15:21 +0300411 */
412int pci_ep_stop(struct udevice *dev);
413
414#endif