| /* SPDX-License-Identifier: GPL-2.0+ */ | |
| /* | |
| * Adapted from Linux kernel driver | |
| * Copyright (C) 2017 Texas Instruments | |
| * Author: Kishon Vijay Abraham I <kishon@ti.com> | |
| * | |
| * (C) Copyright 2019 | |
| * Ramon Fried <ramon.fried@gmail.com> | |
| */ | |
| #ifndef _PCI_EP_H | |
| #define _PCI_EP_H | |
| #include <pci.h> | |
| /** | |
| * enum pci_interrupt_pin - PCI INTx interrupt values | |
| * @PCI_INTERRUPT_UNKNOWN: Unknown or unassigned interrupt | |
| * @PCI_INTERRUPT_INTA: PCI INTA pin | |
| * @PCI_INTERRUPT_INTB: PCI INTB pin | |
| * @PCI_INTERRUPT_INTC: PCI INTC pin | |
| * @PCI_INTERRUPT_INTD: PCI INTD pin | |
| * | |
| * Corresponds to values for legacy PCI INTx interrupts, as can be found in the | |
| * PCI_INTERRUPT_PIN register. | |
| */ | |
| enum pci_interrupt_pin { | |
| PCI_INTERRUPT_UNKNOWN, | |
| PCI_INTERRUPT_INTA, | |
| PCI_INTERRUPT_INTB, | |
| PCI_INTERRUPT_INTC, | |
| PCI_INTERRUPT_INTD, | |
| }; | |
| enum pci_barno { | |
| BAR_0, | |
| BAR_1, | |
| BAR_2, | |
| BAR_3, | |
| BAR_4, | |
| BAR_5, | |
| }; | |
| enum pci_ep_irq_type { | |
| PCI_EP_IRQ_UNKNOWN, | |
| PCI_EP_IRQ_LEGACY, | |
| PCI_EP_IRQ_MSI, | |
| PCI_EP_IRQ_MSIX, | |
| }; | |
| /** | |
| * struct pci_bar - represents the BAR (Base Address Register) of EP device | |
| * @phys_addr: physical address that should be mapped to the BAR | |
| * @size: the size of the address space present in BAR | |
| * pci_barno: number of pci BAR to set (0..5) | |
| * @flags: BAR access flags | |
| */ | |
| struct pci_bar { | |
| dma_addr_t phys_addr; | |
| size_t size; | |
| enum pci_barno barno; | |
| int flags; | |
| }; | |
| /** | |
| * struct pci_ep_header - represents standard configuration header | |
| * @vendorid: identifies device manufacturer | |
| * @deviceid: identifies a particular device | |
| * @revid: specifies a device-specific revision identifier | |
| * @progif_code: identifies a specific register-level programming interface | |
| * @subclass_code: identifies more specifically the function of the device | |
| * @baseclass_code: broadly classifies the type of function the device performs | |
| * @cache_line_size: specifies the system cacheline size in units of DWORDs | |
| * @subsys_vendor_id: vendor of the add-in card or subsystem | |
| * @subsys_id: id specific to vendor | |
| * @interrupt_pin: interrupt pin the device (or device function) uses | |
| */ | |
| struct pci_ep_header { | |
| u16 vendorid; | |
| u16 deviceid; | |
| u8 revid; | |
| u8 progif_code; | |
| u8 subclass_code; | |
| u8 baseclass_code; | |
| u8 cache_line_size; | |
| u16 subsys_vendor_id; | |
| u16 subsys_id; | |
| enum pci_interrupt_pin interrupt_pin; | |
| }; | |
| /* PCI endpoint operations */ | |
| struct pci_ep_ops { | |
| /** | |
| * write_header() - Write a PCI configuration space header | |
| * | |
| * @dev: device to write to | |
| * @func_num: EP function to fill | |
| * @hdr: header to write | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*write_header)(struct udevice *dev, uint func_num, | |
| struct pci_ep_header *hdr); | |
| /** | |
| * read_header() - Read a PCI configuration space header | |
| * | |
| * @dev: device to write to | |
| * @func_num: EP function to fill | |
| * @hdr: header to read to | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*read_header)(struct udevice *dev, uint func_num, | |
| struct pci_ep_header *hdr); | |
| /** | |
| * set_bar() - Set BAR (Base Address Register) properties | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @bar: bar data | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*set_bar)(struct udevice *dev, uint func_num, | |
| struct pci_bar *bar); | |
| /** | |
| * read_bar() - Read BAR (Base Address Register) properties | |
| * | |
| * @dev: device to read | |
| * @func_num: EP function to read | |
| * @bar: struct to copy data to | |
| * @barno: bar number to read | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*read_bar)(struct udevice *dev, uint func_num, | |
| struct pci_bar *bar, enum pci_barno barno); | |
| /** | |
| * clear_bar() - clear BAR (Base Address Register) | |
| * | |
| * @dev: device to clear | |
| * @func_num: EP function to clear | |
| * @bar: bar number | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*clear_bar)(struct udevice *dev, uint func_num, | |
| enum pci_barno bar); | |
| /** | |
| * map_addr() - map CPU address to PCI address | |
| * | |
| * outband region is used in order to generate PCI read/write | |
| * transaction from local memory/write. | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @addr: local physical address base | |
| * @pci_addr: pci address to translate to | |
| * @size: region size | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*map_addr)(struct udevice *dev, uint func_num, | |
| phys_addr_t addr, u64 pci_addr, size_t size); | |
| /** | |
| * unmap_addr() - unmap CPU address to PCI address | |
| * | |
| * unmap previously mapped region. | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @addr: local physical address base | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*unmap_addr)(struct udevice *dev, uint func_num, | |
| phys_addr_t addr); | |
| /** | |
| * set_msi() - set msi capability property | |
| * | |
| * set the number of required MSI vectors the device | |
| * needs for operation. | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @interrupts: required interrupts count | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*set_msi)(struct udevice *dev, uint func_num, uint interrupts); | |
| /** | |
| * get_msi() - get the number of MSI interrupts allocated by the host. | |
| * | |
| * Read the Multiple Message Enable bitfield from | |
| * Message control register. | |
| * | |
| * @dev: device to use | |
| * @func_num: EP function to use | |
| * @return msi count if OK, -EINVAL if msi were not enabled at host. | |
| */ | |
| int (*get_msi)(struct udevice *dev, uint func_num); | |
| /** | |
| * set_msix() - set msix capability property | |
| * | |
| * set the number of required MSIx vectors the device | |
| * needs for operation. | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @interrupts: required interrupts count | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*set_msix)(struct udevice *dev, uint func_num, | |
| uint interrupts); | |
| /** | |
| * get_msix() - get the number of MSIx interrupts allocated by the host. | |
| * | |
| * Read the Multiple Message Enable bitfield from | |
| * Message control register. | |
| * | |
| * @dev: device to use | |
| * @func_num: EP function to use | |
| * @return msi count if OK, -EINVAL if msi were not enabled at host. | |
| */ | |
| int (*get_msix)(struct udevice *dev, uint func_num); | |
| /** | |
| * raise_irq() - raise a legacy, MSI or MSI-X interrupt | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @type: type of irq to send | |
| * @interrupt_num: interrupt vector to use | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*raise_irq)(struct udevice *dev, uint func_num, | |
| enum pci_ep_irq_type type, uint interrupt_num); | |
| /** | |
| * start() - start the PCI link | |
| * | |
| * @dev: device to set | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*start)(struct udevice *dev); | |
| /** | |
| * stop() - stop the PCI link | |
| * | |
| * @dev: device to set | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int (*stop)(struct udevice *dev); | |
| }; | |
| #define pci_ep_get_ops(dev) ((struct pci_ep_ops *)(dev)->driver->ops) | |
| /** | |
| * pci_ep_write_header() - Write a PCI configuration space header | |
| * | |
| * @dev: device to write to | |
| * @func_num: EP function to fill | |
| * @hdr: header to write | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_write_header(struct udevice *dev, uint func_num, | |
| struct pci_ep_header *hdr); | |
| /** | |
| * dm_pci_ep_read_header() - Read a PCI configuration space header | |
| * | |
| * @dev: device to write to | |
| * @func_num: EP function to fill | |
| * @hdr: header to read to | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_read_header(struct udevice *dev, uint func_num, | |
| struct pci_ep_header *hdr); | |
| /** | |
| * pci_ep_set_bar() - Set BAR (Base Address Register) properties | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @bar: bar data | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_set_bar(struct udevice *dev, uint func_num, struct pci_bar *bar); | |
| /** | |
| * pci_ep_read_bar() - Read BAR (Base Address Register) properties | |
| * | |
| * @dev: device to read | |
| * @func_num: EP function to read | |
| * @bar: struct to copy data to | |
| * @barno: bar number to read | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_read_bar(struct udevice *dev, uint func_no, struct pci_bar *ep_bar, | |
| enum pci_barno barno); | |
| /** | |
| * pci_ep_clear_bar() - Clear BAR (Base Address Register) | |
| * mark the BAR as empty so host won't map it. | |
| * @dev: device to clear | |
| * @func_num: EP function to clear | |
| * @bar: bar number | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_clear_bar(struct udevice *dev, uint func_num, enum pci_barno bar); | |
| /** | |
| * pci_ep_map_addr() - map CPU address to PCI address | |
| * | |
| * outband region is used in order to generate PCI read/write | |
| * transaction from local memory/write. | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @addr: local physical address base | |
| * @pci_addr: pci address to translate to | |
| * @size: region size | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_map_addr(struct udevice *dev, uint func_num, phys_addr_t addr, | |
| u64 pci_addr, size_t size); | |
| /** | |
| * pci_ep_unmap_addr() - unmap CPU address to PCI address | |
| * | |
| * unmap previously mapped region. | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @addr: local physical address base | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_unmap_addr(struct udevice *dev, uint func_num, phys_addr_t addr); | |
| /** | |
| * pci_ep_set_msi() - set msi capability property | |
| * | |
| * set the number of required MSI vectors the device | |
| * needs for operation. | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @interrupts: required interrupts count | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_set_msi(struct udevice *dev, uint func_num, uint interrupts); | |
| /** | |
| * pci_ep_get_msi() - get the number of MSI interrupts allocated by the host. | |
| * | |
| * Read the Multiple Message Enable bitfield from | |
| * Message control register. | |
| * | |
| * @dev: device to use | |
| * @func_num: EP function to use | |
| * @return msi count if OK, -EINVAL if msi were not enabled at host. | |
| */ | |
| int pci_ep_get_msi(struct udevice *dev, uint func_num); | |
| /** | |
| * pci_ep_set_msix() - set msi capability property | |
| * | |
| * set the number of required MSIx vectors the device | |
| * needs for operation. | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @interrupts: required interrupts count | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_set_msix(struct udevice *dev, uint func_num, uint interrupts); | |
| /** | |
| * pci_ep_get_msix() - get the number of MSIx interrupts allocated by the host. | |
| * | |
| * Read the Multiple Message Enable bitfield from | |
| * Message control register. | |
| * | |
| * @dev: device to use | |
| * @func_num: EP function to use | |
| * @return msi count if OK, -EINVAL if msi were not enabled at host. | |
| */ | |
| int pci_ep_get_msix(struct udevice *dev, uint func_num); | |
| /** | |
| * pci_ep_raise_irq() - raise a legacy, MSI or MSI-X interrupt | |
| * | |
| * @dev: device to set | |
| * @func_num: EP function to set | |
| * @type: type of irq to send | |
| * @interrupt_num: interrupt vector to use | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_raise_irq(struct udevice *dev, uint func_num, | |
| enum pci_ep_irq_type type, uint interrupt_num); | |
| /** | |
| * pci_ep_start() - start the PCI link | |
| * | |
| * Enable PCI endpoint device and start link | |
| * process. | |
| * | |
| * @dev: device to set | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_start(struct udevice *dev); | |
| /** | |
| * pci_ep_stop() - stop the PCI link | |
| * | |
| * Disable PCI endpoint device and stop | |
| * link. | |
| * | |
| * @dev: device to set | |
| * @return 0 if OK, -ve on error | |
| */ | |
| int pci_ep_stop(struct udevice *dev); | |
| #endif |