1d8946fc3SChangbin Du.. SPDX-License-Identifier: GPL-2.0 2d8946fc3SChangbin Du 3d8946fc3SChangbin Du:Author: Kishon Vijay Abraham I <kishon@ti.com> 4d8946fc3SChangbin Du 5d8946fc3SChangbin DuThis document is a guide to use the PCI Endpoint Framework in order to create 6d8946fc3SChangbin Duendpoint controller driver, endpoint function driver, and using configfs 7d8946fc3SChangbin Duinterface to bind the function driver to the controller driver. 8d8946fc3SChangbin Du 9d8946fc3SChangbin DuIntroduction 10d8946fc3SChangbin Du============ 11d8946fc3SChangbin Du 12d8946fc3SChangbin DuLinux has a comprehensive PCI subsystem to support PCI controllers that 13d8946fc3SChangbin Duoperates in Root Complex mode. The subsystem has capability to scan PCI bus, 14d8946fc3SChangbin Duassign memory resources and IRQ resources, load PCI driver (based on 15d8946fc3SChangbin Duvendor ID, device ID), support other services like hot-plug, power management, 16d8946fc3SChangbin Duadvanced error reporting and virtual channels. 17d8946fc3SChangbin Du 18d8946fc3SChangbin DuHowever the PCI controller IP integrated in some SoCs is capable of operating 19d8946fc3SChangbin Dueither in Root Complex mode or Endpoint mode. PCI Endpoint Framework will 20d8946fc3SChangbin Duadd endpoint mode support in Linux. This will help to run Linux in an 21d8946fc3SChangbin DuEP system which can have a wide variety of use cases from testing or 22d8946fc3SChangbin Duvalidation, co-processor accelerator, etc. 23d8946fc3SChangbin Du 24d8946fc3SChangbin DuPCI Endpoint Core 25d8946fc3SChangbin Du================= 26d8946fc3SChangbin Du 27d8946fc3SChangbin DuThe PCI Endpoint Core layer comprises 3 components: the Endpoint Controller 28d8946fc3SChangbin Dulibrary, the Endpoint Function library, and the configfs layer to bind the 29d8946fc3SChangbin Duendpoint function with the endpoint controller. 30d8946fc3SChangbin Du 31d8946fc3SChangbin DuPCI Endpoint Controller(EPC) Library 32d8946fc3SChangbin Du------------------------------------ 33d8946fc3SChangbin Du 34d8946fc3SChangbin DuThe EPC library provides APIs to be used by the controller that can operate 35d8946fc3SChangbin Duin endpoint mode. It also provides APIs to be used by function driver/library 36d8946fc3SChangbin Duin order to implement a particular endpoint function. 37d8946fc3SChangbin Du 38d8946fc3SChangbin DuAPIs for the PCI controller Driver 39d8946fc3SChangbin Du~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 40d8946fc3SChangbin Du 41d8946fc3SChangbin DuThis section lists the APIs that the PCI Endpoint core provides to be used 42d8946fc3SChangbin Duby the PCI controller driver. 43d8946fc3SChangbin Du 44d8946fc3SChangbin Du* devm_pci_epc_create()/pci_epc_create() 45d8946fc3SChangbin Du 46d8946fc3SChangbin Du The PCI controller driver should implement the following ops: 47d8946fc3SChangbin Du 48d8946fc3SChangbin Du * write_header: ops to populate configuration space header 49d8946fc3SChangbin Du * set_bar: ops to configure the BAR 50d8946fc3SChangbin Du * clear_bar: ops to reset the BAR 51d8946fc3SChangbin Du * alloc_addr_space: ops to allocate in PCI controller address space 52d8946fc3SChangbin Du * free_addr_space: ops to free the allocated address space 53d8946fc3SChangbin Du * raise_irq: ops to raise a legacy, MSI or MSI-X interrupt 54d8946fc3SChangbin Du * start: ops to start the PCI link 55d8946fc3SChangbin Du * stop: ops to stop the PCI link 56d8946fc3SChangbin Du 57d8946fc3SChangbin Du The PCI controller driver can then create a new EPC device by invoking 58d8946fc3SChangbin Du devm_pci_epc_create()/pci_epc_create(). 59d8946fc3SChangbin Du 60d8946fc3SChangbin Du* devm_pci_epc_destroy()/pci_epc_destroy() 61d8946fc3SChangbin Du 62d8946fc3SChangbin Du The PCI controller driver can destroy the EPC device created by either 63d8946fc3SChangbin Du devm_pci_epc_create() or pci_epc_create() using devm_pci_epc_destroy() or 64d8946fc3SChangbin Du pci_epc_destroy(). 65d8946fc3SChangbin Du 66d8946fc3SChangbin Du* pci_epc_linkup() 67d8946fc3SChangbin Du 68d8946fc3SChangbin Du In order to notify all the function devices that the EPC device to which 69d8946fc3SChangbin Du they are linked has established a link with the host, the PCI controller 70d8946fc3SChangbin Du driver should invoke pci_epc_linkup(). 71d8946fc3SChangbin Du 72d8946fc3SChangbin Du* pci_epc_mem_init() 73d8946fc3SChangbin Du 74d8946fc3SChangbin Du Initialize the pci_epc_mem structure used for allocating EPC addr space. 75d8946fc3SChangbin Du 76d8946fc3SChangbin Du* pci_epc_mem_exit() 77d8946fc3SChangbin Du 78d8946fc3SChangbin Du Cleanup the pci_epc_mem structure allocated during pci_epc_mem_init(). 79d8946fc3SChangbin Du 80d8946fc3SChangbin Du 817fdde0f9SBryce WilleyEPC APIs for the PCI Endpoint Function Driver 827fdde0f9SBryce Willey~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 83d8946fc3SChangbin Du 84d8946fc3SChangbin DuThis section lists the APIs that the PCI Endpoint core provides to be used 85d8946fc3SChangbin Duby the PCI endpoint function driver. 86d8946fc3SChangbin Du 87d8946fc3SChangbin Du* pci_epc_write_header() 88d8946fc3SChangbin Du 89d8946fc3SChangbin Du The PCI endpoint function driver should use pci_epc_write_header() to 90d8946fc3SChangbin Du write the standard configuration header to the endpoint controller. 91d8946fc3SChangbin Du 92d8946fc3SChangbin Du* pci_epc_set_bar() 93d8946fc3SChangbin Du 94d8946fc3SChangbin Du The PCI endpoint function driver should use pci_epc_set_bar() to configure 95d8946fc3SChangbin Du the Base Address Register in order for the host to assign PCI addr space. 96d8946fc3SChangbin Du Register space of the function driver is usually configured 97d8946fc3SChangbin Du using this API. 98d8946fc3SChangbin Du 99d8946fc3SChangbin Du* pci_epc_clear_bar() 100d8946fc3SChangbin Du 101d8946fc3SChangbin Du The PCI endpoint function driver should use pci_epc_clear_bar() to reset 102d8946fc3SChangbin Du the BAR. 103d8946fc3SChangbin Du 104d8946fc3SChangbin Du* pci_epc_raise_irq() 105d8946fc3SChangbin Du 106d8946fc3SChangbin Du The PCI endpoint function driver should use pci_epc_raise_irq() to raise 107d8946fc3SChangbin Du Legacy Interrupt, MSI or MSI-X Interrupt. 108d8946fc3SChangbin Du 109d8946fc3SChangbin Du* pci_epc_mem_alloc_addr() 110d8946fc3SChangbin Du 111d8946fc3SChangbin Du The PCI endpoint function driver should use pci_epc_mem_alloc_addr(), to 112d8946fc3SChangbin Du allocate memory address from EPC addr space which is required to access 113d8946fc3SChangbin Du RC's buffer 114d8946fc3SChangbin Du 115d8946fc3SChangbin Du* pci_epc_mem_free_addr() 116d8946fc3SChangbin Du 117d8946fc3SChangbin Du The PCI endpoint function driver should use pci_epc_mem_free_addr() to 118d8946fc3SChangbin Du free the memory space allocated using pci_epc_mem_alloc_addr(). 119d8946fc3SChangbin Du 1207fdde0f9SBryce WilleyOther EPC APIs 1217fdde0f9SBryce Willey~~~~~~~~~~~~~~ 122d8946fc3SChangbin Du 123d8946fc3SChangbin DuThere are other APIs provided by the EPC library. These are used for binding 124d8946fc3SChangbin Duthe EPF device with EPC device. pci-ep-cfs.c can be used as reference for 125d8946fc3SChangbin Duusing these APIs. 126d8946fc3SChangbin Du 127d8946fc3SChangbin Du* pci_epc_get() 128d8946fc3SChangbin Du 129d8946fc3SChangbin Du Get a reference to the PCI endpoint controller based on the device name of 130d8946fc3SChangbin Du the controller. 131d8946fc3SChangbin Du 132d8946fc3SChangbin Du* pci_epc_put() 133d8946fc3SChangbin Du 134d8946fc3SChangbin Du Release the reference to the PCI endpoint controller obtained using 135d8946fc3SChangbin Du pci_epc_get() 136d8946fc3SChangbin Du 137d8946fc3SChangbin Du* pci_epc_add_epf() 138d8946fc3SChangbin Du 139d8946fc3SChangbin Du Add a PCI endpoint function to a PCI endpoint controller. A PCIe device 140d8946fc3SChangbin Du can have up to 8 functions according to the specification. 141d8946fc3SChangbin Du 142d8946fc3SChangbin Du* pci_epc_remove_epf() 143d8946fc3SChangbin Du 144d8946fc3SChangbin Du Remove the PCI endpoint function from PCI endpoint controller. 145d8946fc3SChangbin Du 146d8946fc3SChangbin Du* pci_epc_start() 147d8946fc3SChangbin Du 148d8946fc3SChangbin Du The PCI endpoint function driver should invoke pci_epc_start() once it 149d8946fc3SChangbin Du has configured the endpoint function and wants to start the PCI link. 150d8946fc3SChangbin Du 151d8946fc3SChangbin Du* pci_epc_stop() 152d8946fc3SChangbin Du 153d8946fc3SChangbin Du The PCI endpoint function driver should invoke pci_epc_stop() to stop 154d8946fc3SChangbin Du the PCI LINK. 155d8946fc3SChangbin Du 156d8946fc3SChangbin Du 157d8946fc3SChangbin DuPCI Endpoint Function(EPF) Library 158d8946fc3SChangbin Du---------------------------------- 159d8946fc3SChangbin Du 160d8946fc3SChangbin DuThe EPF library provides APIs to be used by the function driver and the EPC 161d8946fc3SChangbin Dulibrary to provide endpoint mode functionality. 162d8946fc3SChangbin Du 1637fdde0f9SBryce WilleyEPF APIs for the PCI Endpoint Function Driver 1647fdde0f9SBryce Willey~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 165d8946fc3SChangbin Du 166d8946fc3SChangbin DuThis section lists the APIs that the PCI Endpoint core provides to be used 167d8946fc3SChangbin Duby the PCI endpoint function driver. 168d8946fc3SChangbin Du 169d8946fc3SChangbin Du* pci_epf_register_driver() 170d8946fc3SChangbin Du 171d8946fc3SChangbin Du The PCI Endpoint Function driver should implement the following ops: 172d8946fc3SChangbin Du * bind: ops to perform when a EPC device has been bound to EPF device 173d8946fc3SChangbin Du * unbind: ops to perform when a binding has been lost between a EPC 174d8946fc3SChangbin Du device and EPF device 175d8946fc3SChangbin Du * linkup: ops to perform when the EPC device has established a 176d8946fc3SChangbin Du connection with a host system 177d8946fc3SChangbin Du 178d8946fc3SChangbin Du The PCI Function driver can then register the PCI EPF driver by using 179d8946fc3SChangbin Du pci_epf_register_driver(). 180d8946fc3SChangbin Du 181d8946fc3SChangbin Du* pci_epf_unregister_driver() 182d8946fc3SChangbin Du 183d8946fc3SChangbin Du The PCI Function driver can unregister the PCI EPF driver by using 184d8946fc3SChangbin Du pci_epf_unregister_driver(). 185d8946fc3SChangbin Du 186d8946fc3SChangbin Du* pci_epf_alloc_space() 187d8946fc3SChangbin Du 188d8946fc3SChangbin Du The PCI Function driver can allocate space for a particular BAR using 189d8946fc3SChangbin Du pci_epf_alloc_space(). 190d8946fc3SChangbin Du 191d8946fc3SChangbin Du* pci_epf_free_space() 192d8946fc3SChangbin Du 193d8946fc3SChangbin Du The PCI Function driver can free the allocated space 194d8946fc3SChangbin Du (using pci_epf_alloc_space) by invoking pci_epf_free_space(). 195d8946fc3SChangbin Du 196d8946fc3SChangbin DuAPIs for the PCI Endpoint Controller Library 197d8946fc3SChangbin Du~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ 198d8946fc3SChangbin Du 199d8946fc3SChangbin DuThis section lists the APIs that the PCI Endpoint core provides to be used 200d8946fc3SChangbin Duby the PCI endpoint controller library. 201d8946fc3SChangbin Du 202d8946fc3SChangbin Du* pci_epf_linkup() 203d8946fc3SChangbin Du 204d8946fc3SChangbin Du The PCI endpoint controller library invokes pci_epf_linkup() when the 205d8946fc3SChangbin Du EPC device has established the connection to the host. 206d8946fc3SChangbin Du 2077fdde0f9SBryce WilleyOther EPF APIs 2087fdde0f9SBryce Willey~~~~~~~~~~~~~~ 209d8946fc3SChangbin Du 210d8946fc3SChangbin DuThere are other APIs provided by the EPF library. These are used to notify 211d8946fc3SChangbin Duthe function driver when the EPF device is bound to the EPC device. 212d8946fc3SChangbin Dupci-ep-cfs.c can be used as reference for using these APIs. 213d8946fc3SChangbin Du 214d8946fc3SChangbin Du* pci_epf_create() 215d8946fc3SChangbin Du 216d8946fc3SChangbin Du Create a new PCI EPF device by passing the name of the PCI EPF device. 217*4ef7f74eSRandy Dunlap This name will be used to bind the EPF device to a EPF driver. 218d8946fc3SChangbin Du 219d8946fc3SChangbin Du* pci_epf_destroy() 220d8946fc3SChangbin Du 221d8946fc3SChangbin Du Destroy the created PCI EPF device. 222d8946fc3SChangbin Du 223d8946fc3SChangbin Du* pci_epf_bind() 224d8946fc3SChangbin Du 225d8946fc3SChangbin Du pci_epf_bind() should be invoked when the EPF device has been bound to 226d8946fc3SChangbin Du a EPC device. 227d8946fc3SChangbin Du 228d8946fc3SChangbin Du* pci_epf_unbind() 229d8946fc3SChangbin Du 230d8946fc3SChangbin Du pci_epf_unbind() should be invoked when the binding between EPC device 231d8946fc3SChangbin Du and EPF device is lost. 232