aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2017-04-28 11:32:33 -0400
committerBjorn Helgaas <bhelgaas@google.com>2017-04-28 11:32:33 -0400
commit9b2707ca56f98d1184857384ebecd23e1f06c807 (patch)
treebed29b8550b6e10eec99f726062ac7b94e1f669e
parentc1ae3cfa0e89fa1a7ecc4c99031f5e9ae99d9201 (diff)
parent2c949ce38f4e81d7487f165fa3b8f77d74a2a6c4 (diff)
Merge branch 'pci/host-designware' into next
* pci/host-designware: ARM: DRA7: clockdomain: Change the CLKTRCTRL of CM_PCIE_CLKSTCTRL to SW_WKUP MAINTAINERS: Add PCI Endpoint maintainer Documentation: PCI: Add userguide for PCI endpoint test function tools: PCI: Add sample test script to invoke pcitest tools: PCI: Add a userspace tool to test PCI endpoint Documentation: misc-devices: Add Documentation for pci-endpoint-test driver misc: Add host side PCI driver for PCI test function device PCI: Add device IDs for DRA74x and DRA72x dt-bindings: PCI: dra7xx: Add DT bindings to enable unaligned access PCI: dwc: dra7xx: Workaround for errata id i870 dt-bindings: PCI: dra7xx: Add DT bindings for PCI dra7xx EP mode PCI: dwc: dra7xx: Add EP mode support PCI: dwc: dra7xx: Facilitate wrapper and MSI interrupts to be enabled independently dt-bindings: PCI: Add DT bindings for PCI designware EP mode PCI: dwc: designware: Add EP mode support Documentation: PCI: Add binding documentation for pci-test endpoint function PCI: endpoint: functions: Add an EP function to test PCI Documentation: PCI: Add specification for the *PCI test* function device PCI: endpoint: Create configfs entry for EPC device and EPF driver Documentation: PCI: Guide to use PCI endpoint configfs PCI: endpoint: Introduce configfs entry for configuring EP functions Documentation: PCI: Guide to use PCI Endpoint Core Layer PCI: endpoint: Add EP core layer to enable EP controller and EP functions PCI: dwc: dra7xx: Push request_irq() call to the bottom of probe PCI: dwc: designware: Move _unroll configurations to a separate function PCI: dwc: all: Modify dbi accessors to access data of 4/2/1 bytes PCI: dwc: all: Modify dbi accessors to take dbi_base as argument PCI: dwc: artpec6: Populate cpu_addr_fixup ops PCI: dwc: dra7xx: Populate cpu_addr_fixup ops PCI: dwc: designware: Add new *ops* for CPU addr fixup PCI: dwc: Fix uninitialized variable in dw_handle_msi_irq() PCI: dwc: Unindent dw_handle_msi_irq() loop PCI: dwc: Fix dw_pcie_ops NULL pointer dereference PCI: dwc: Select PCI_HOST_COMMON for hisi PCI: thunder-pem: Fix legacy firmware PEM-specific resources PCI: thunder-pem: Add legacy firmware support for Cavium ThunderX host controller PCI: thunder-pem: Use Cavium assigned hardware ID for ThunderX host controller PCI: iproc: Save host bridge window resource in struct iproc_pcie PCI/ASPM: Always set link->downstream to avoid NULL dereference on remove PCI: Prevent VPD access for QLogic ISP2722 PCI: exynos: Initialize elbi_base even when using PHY framework
-rw-r--r--Documentation/PCI/00-INDEX10
-rw-r--r--Documentation/PCI/endpoint/function/binding/pci-test.txt17
-rw-r--r--Documentation/PCI/endpoint/pci-endpoint-cfs.txt105
-rw-r--r--Documentation/PCI/endpoint/pci-endpoint.txt215
-rw-r--r--Documentation/PCI/endpoint/pci-test-function.txt66
-rw-r--r--Documentation/PCI/endpoint/pci-test-howto.txt179
-rw-r--r--Documentation/devicetree/bindings/pci/designware-pcie.txt26
-rw-r--r--Documentation/devicetree/bindings/pci/ti-pci.txt42
-rw-r--r--Documentation/misc-devices/pci-endpoint-test.txt35
-rw-r--r--MAINTAINERS9
-rw-r--r--arch/arm/mach-omap2/clockdomains7xx_data.c2
-rw-r--r--drivers/Makefile2
-rw-r--r--drivers/misc/Kconfig7
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/pci_endpoint_test.c534
-rw-r--r--drivers/pci/Kconfig1
-rw-r--r--drivers/pci/dwc/Kconfig37
-rw-r--r--drivers/pci/dwc/Makefile5
-rw-r--r--drivers/pci/dwc/pci-dra7xx.c293
-rw-r--r--drivers/pci/dwc/pci-exynos.c22
-rw-r--r--drivers/pci/dwc/pcie-artpec6.c15
-rw-r--r--drivers/pci/dwc/pcie-designware-ep.c342
-rw-r--r--drivers/pci/dwc/pcie-designware-host.c27
-rw-r--r--drivers/pci/dwc/pcie-designware-plat.c4
-rw-r--r--drivers/pci/dwc/pcie-designware.c258
-rw-r--r--drivers/pci/dwc/pcie-designware.h135
-rw-r--r--drivers/pci/endpoint/Kconfig31
-rw-r--r--drivers/pci/endpoint/Makefile7
-rw-r--r--drivers/pci/endpoint/functions/Kconfig12
-rw-r--r--drivers/pci/endpoint/functions/Makefile5
-rw-r--r--drivers/pci/endpoint/functions/pci-epf-test.c510
-rw-r--r--drivers/pci/endpoint/pci-ep-cfs.c509
-rw-r--r--drivers/pci/endpoint/pci-epc-core.c580
-rw-r--r--drivers/pci/endpoint/pci-epc-mem.c143
-rw-r--r--drivers/pci/endpoint/pci-epf-core.c359
-rw-r--r--drivers/pci/host/pci-thunder-pem.c64
-rw-r--r--drivers/pci/host/pcie-iproc-bcma.c24
-rw-r--r--drivers/pci/host/pcie-iproc-platform.c19
-rw-r--r--drivers/pci/host/pcie-iproc.h1
-rw-r--r--drivers/pci/pcie/aspm.c5
-rw-r--r--drivers/pci/quirks.c1
-rw-r--r--include/linux/mod_devicetable.h10
-rw-r--r--include/linux/pci-ep-cfs.h41
-rw-r--r--include/linux/pci-epc.h144
-rw-r--r--include/linux/pci-epf.h162
-rw-r--r--include/linux/pci_ids.h2
-rw-r--r--include/uapi/linux/Kbuild1
-rw-r--r--include/uapi/linux/pcitest.h19
-rw-r--r--tools/pci/pcitest.c186
-rw-r--r--tools/pci/pcitest.sh56
50 files changed, 5122 insertions, 158 deletions
diff --git a/Documentation/PCI/00-INDEX b/Documentation/PCI/00-INDEX
index 147231f1613e..00c9a90b6f38 100644
--- a/Documentation/PCI/00-INDEX
+++ b/Documentation/PCI/00-INDEX
@@ -12,3 +12,13 @@ pci.txt
12 - info on the PCI subsystem for device driver authors 12 - info on the PCI subsystem for device driver authors
13pcieaer-howto.txt 13pcieaer-howto.txt
14 - the PCI Express Advanced Error Reporting Driver Guide HOWTO 14 - the PCI Express Advanced Error Reporting Driver Guide HOWTO
15endpoint/pci-endpoint.txt
16 - guide to add endpoint controller driver and endpoint function driver.
17endpoint/pci-endpoint-cfs.txt
18 - guide to use configfs to configure the PCI endpoint function.
19endpoint/pci-test-function.txt
20 - specification of *PCI test* function device.
21endpoint/pci-test-howto.txt
22 - userguide for PCI endpoint test function.
23endpoint/function/binding/
24 - binding documentation for PCI endpoint function
diff --git a/Documentation/PCI/endpoint/function/binding/pci-test.txt b/Documentation/PCI/endpoint/function/binding/pci-test.txt
new file mode 100644
index 000000000000..3b68b955fb50
--- /dev/null
+++ b/Documentation/PCI/endpoint/function/binding/pci-test.txt
@@ -0,0 +1,17 @@
1PCI TEST ENDPOINT FUNCTION
2
3name: Should be "pci_epf_test" to bind to the pci_epf_test driver.
4
5Configurable Fields:
6vendorid : should be 0x104c
7deviceid : should be 0xb500 for DRA74x and 0xb501 for DRA72x
8revid : don't care
9progif_code : don't care
10subclass_code : don't care
11baseclass_code : should be 0xff
12cache_line_size : don't care
13subsys_vendor_id : don't care
14subsys_id : don't care
15interrupt_pin : Should be 1 - INTA, 2 - INTB, 3 - INTC, 4 -INTD
16msi_interrupts : Should be 1 to 32 depending on the number of MSI interrupts
17 to test
diff --git a/Documentation/PCI/endpoint/pci-endpoint-cfs.txt b/Documentation/PCI/endpoint/pci-endpoint-cfs.txt
new file mode 100644
index 000000000000..d740f29960a4
--- /dev/null
+++ b/Documentation/PCI/endpoint/pci-endpoint-cfs.txt
@@ -0,0 +1,105 @@
1 CONFIGURING PCI ENDPOINT USING CONFIGFS
2 Kishon Vijay Abraham I <kishon@ti.com>
3
4The PCI Endpoint Core exposes configfs entry (pci_ep) to configure the
5PCI endpoint function and to bind the endpoint function
6with the endpoint controller. (For introducing other mechanisms to
7configure the PCI Endpoint Function refer to [1]).
8
9*) Mounting configfs
10
11The PCI Endpoint Core layer creates pci_ep directory in the mounted configfs
12directory. configfs can be mounted using the following command.
13
14 mount -t configfs none /sys/kernel/config
15
16*) Directory Structure
17
18The pci_ep configfs has two directories at its root: controllers and
19functions. Every EPC device present in the system will have an entry in
20the *controllers* directory and and every EPF driver present in the system
21will have an entry in the *functions* directory.
22
23/sys/kernel/config/pci_ep/
24 .. controllers/
25 .. functions/
26
27*) Creating EPF Device
28
29Every registered EPF driver will be listed in controllers directory. The
30entries corresponding to EPF driver will be created by the EPF core.
31
32/sys/kernel/config/pci_ep/functions/
33 .. <EPF Driver1>/
34 ... <EPF Device 11>/
35 ... <EPF Device 21>/
36 .. <EPF Driver2>/
37 ... <EPF Device 12>/
38 ... <EPF Device 22>/
39
40In order to create a <EPF device> of the type probed by <EPF Driver>, the
41user has to create a directory inside <EPF DriverN>.
42
43Every <EPF device> directory consists of the following entries that can be
44used to configure the standard configuration header of the endpoint function.
45(These entries are created by the framework when any new <EPF Device> is
46created)
47
48 .. <EPF Driver1>/
49 ... <EPF Device 11>/
50 ... vendorid
51 ... deviceid
52 ... revid
53 ... progif_code
54 ... subclass_code
55 ... baseclass_code
56 ... cache_line_size
57 ... subsys_vendor_id
58 ... subsys_id
59 ... interrupt_pin
60
61*) EPC Device
62
63Every registered EPC device will be listed in controllers directory. The
64entries corresponding to EPC device will be created by the EPC core.
65
66/sys/kernel/config/pci_ep/controllers/
67 .. <EPC Device1>/
68 ... <Symlink EPF Device11>/
69 ... <Symlink EPF Device12>/
70 ... start
71 .. <EPC Device2>/
72 ... <Symlink EPF Device21>/
73 ... <Symlink EPF Device22>/
74 ... start
75
76The <EPC Device> directory will have a list of symbolic links to
77<EPF Device>. These symbolic links should be created by the user to
78represent the functions present in the endpoint device.
79
80The <EPC Device> directory will also have a *start* field. Once
81"1" is written to this field, the endpoint device will be ready to
82establish the link with the host. This is usually done after
83all the EPF devices are created and linked with the EPC device.
84
85
86 | controllers/
87 | <Directory: EPC name>/
88 | <Symbolic Link: Function>
89 | start
90 | functions/
91 | <Directory: EPF driver>/
92 | <Directory: EPF device>/
93 | vendorid
94 | deviceid
95 | revid
96 | progif_code
97 | subclass_code
98 | baseclass_code
99 | cache_line_size
100 | subsys_vendor_id
101 | subsys_id
102 | interrupt_pin
103 | function
104
105[1] -> Documentation/PCI/endpoint/pci-endpoint.txt
diff --git a/Documentation/PCI/endpoint/pci-endpoint.txt b/Documentation/PCI/endpoint/pci-endpoint.txt
new file mode 100644
index 000000000000..9b1d66829290
--- /dev/null
+++ b/Documentation/PCI/endpoint/pci-endpoint.txt
@@ -0,0 +1,215 @@
1 PCI ENDPOINT FRAMEWORK
2 Kishon Vijay Abraham I <kishon@ti.com>
3
4This document is a guide to use the PCI Endpoint Framework in order to create
5endpoint controller driver, endpoint function driver, and using configfs
6interface to bind the function driver to the controller driver.
7
81. Introduction
9
10Linux has a comprehensive PCI subsystem to support PCI controllers that
11operates in Root Complex mode. The subsystem has capability to scan PCI bus,
12assign memory resources and IRQ resources, load PCI driver (based on
13vendor ID, device ID), support other services like hot-plug, power management,
14advanced error reporting and virtual channels.
15
16However the PCI controller IP integrated in some SoCs is capable of operating
17either in Root Complex mode or Endpoint mode. PCI Endpoint Framework will
18add endpoint mode support in Linux. This will help to run Linux in an
19EP system which can have a wide variety of use cases from testing or
20validation, co-processor accelerator, etc.
21
222. PCI Endpoint Core
23
24The PCI Endpoint Core layer comprises 3 components: the Endpoint Controller
25library, the Endpoint Function library, and the configfs layer to bind the
26endpoint function with the endpoint controller.
27
282.1 PCI Endpoint Controller(EPC) Library
29
30The EPC library provides APIs to be used by the controller that can operate
31in endpoint mode. It also provides APIs to be used by function driver/library
32in order to implement a particular endpoint function.
33
342.1.1 APIs for the PCI controller Driver
35
36This section lists the APIs that the PCI Endpoint core provides to be used
37by the PCI controller driver.
38
39*) devm_pci_epc_create()/pci_epc_create()
40
41 The PCI controller driver should implement the following ops:
42 * write_header: ops to populate configuration space header
43 * set_bar: ops to configure the BAR
44 * clear_bar: ops to reset the BAR
45 * alloc_addr_space: ops to allocate in PCI controller address space
46 * free_addr_space: ops to free the allocated address space
47 * raise_irq: ops to raise a legacy or MSI interrupt
48 * start: ops to start the PCI link
49 * stop: ops to stop the PCI link
50
51 The PCI controller driver can then create a new EPC device by invoking
52 devm_pci_epc_create()/pci_epc_create().
53
54*) devm_pci_epc_destroy()/pci_epc_destroy()
55
56 The PCI controller driver can destroy the EPC device created by either
57 devm_pci_epc_create() or pci_epc_create() using devm_pci_epc_destroy() or
58 pci_epc_destroy().
59
60*) pci_epc_linkup()
61
62 In order to notify all the function devices that the EPC device to which
63 they are linked has established a link with the host, the PCI controller
64 driver should invoke pci_epc_linkup().
65
66*) pci_epc_mem_init()
67
68 Initialize the pci_epc_mem structure used for allocating EPC addr space.
69
70*) pci_epc_mem_exit()
71
72 Cleanup the pci_epc_mem structure allocated during pci_epc_mem_init().
73
742.1.2 APIs for the PCI Endpoint Function Driver
75
76This section lists the APIs that the PCI Endpoint core provides to be used
77by the PCI endpoint function driver.
78
79*) pci_epc_write_header()
80
81 The PCI endpoint function driver should use pci_epc_write_header() to
82 write the standard configuration header to the endpoint controller.
83
84*) pci_epc_set_bar()
85
86 The PCI endpoint function driver should use pci_epc_set_bar() to configure
87 the Base Address Register in order for the host to assign PCI addr space.
88 Register space of the function driver is usually configured
89 using this API.
90
91*) pci_epc_clear_bar()
92
93 The PCI endpoint function driver should use pci_epc_clear_bar() to reset
94 the BAR.
95
96*) pci_epc_raise_irq()
97
98 The PCI endpoint function driver should use pci_epc_raise_irq() to raise
99 Legacy Interrupt or MSI Interrupt.
100
101*) pci_epc_mem_alloc_addr()
102
103 The PCI endpoint function driver should use pci_epc_mem_alloc_addr(), to
104 allocate memory address from EPC addr space which is required to access
105 RC's buffer
106
107*) pci_epc_mem_free_addr()
108
109 The PCI endpoint function driver should use pci_epc_mem_free_addr() to
110 free the memory space allocated using pci_epc_mem_alloc_addr().
111
1122.1.3 Other APIs
113
114There are other APIs provided by the EPC library. These are used for binding
115the EPF device with EPC device. pci-ep-cfs.c can be used as reference for
116using these APIs.
117
118*) pci_epc_get()
119
120 Get a reference to the PCI endpoint controller based on the device name of
121 the controller.
122
123*) pci_epc_put()
124
125 Release the reference to the PCI endpoint controller obtained using
126 pci_epc_get()
127
128*) pci_epc_add_epf()
129
130 Add a PCI endpoint function to a PCI endpoint controller. A PCIe device
131 can have up to 8 functions according to the specification.
132
133*) pci_epc_remove_epf()
134
135 Remove the PCI endpoint function from PCI endpoint controller.
136
137*) pci_epc_start()
138
139 The PCI endpoint function driver should invoke pci_epc_start() once it
140 has configured the endpoint function and wants to start the PCI link.
141
142*) pci_epc_stop()
143
144 The PCI endpoint function driver should invoke pci_epc_stop() to stop
145 the PCI LINK.
146
1472.2 PCI Endpoint Function(EPF) Library
148
149The EPF library provides APIs to be used by the function driver and the EPC
150library to provide endpoint mode functionality.
151
1522.2.1 APIs for the PCI Endpoint Function Driver
153
154This section lists the APIs that the PCI Endpoint core provides to be used
155by the PCI endpoint function driver.
156
157*) pci_epf_register_driver()
158
159 The PCI Endpoint Function driver should implement the following ops:
160 * bind: ops to perform when a EPC device has been bound to EPF device
161 * unbind: ops to perform when a binding has been lost between a EPC
162 device and EPF device
163 * linkup: ops to perform when the EPC device has established a
164 connection with a host system
165
166 The PCI Function driver can then register the PCI EPF driver by using
167 pci_epf_register_driver().
168
169*) pci_epf_unregister_driver()
170
171 The PCI Function driver can unregister the PCI EPF driver by using
172 pci_epf_unregister_driver().
173
174*) pci_epf_alloc_space()
175
176 The PCI Function driver can allocate space for a particular BAR using
177 pci_epf_alloc_space().
178
179*) pci_epf_free_space()
180
181 The PCI Function driver can free the allocated space
182 (using pci_epf_alloc_space) by invoking pci_epf_free_space().
183
1842.2.2 APIs for the PCI Endpoint Controller Library
185This section lists the APIs that the PCI Endpoint core provides to be used
186by the PCI endpoint controller library.
187
188*) pci_epf_linkup()
189
190 The PCI endpoint controller library invokes pci_epf_linkup() when the
191 EPC device has established the connection to the host.
192
1932.2.2 Other APIs
194There are other APIs provided by the EPF library. These are used to notify
195the function driver when the EPF device is bound to the EPC device.
196pci-ep-cfs.c can be used as reference for using these APIs.
197
198*) pci_epf_create()
199
200 Create a new PCI EPF device by passing the name of the PCI EPF device.
201 This name will be used to bind the the EPF device to a EPF driver.
202
203*) pci_epf_destroy()
204
205 Destroy the created PCI EPF device.
206
207*) pci_epf_bind()
208
209 pci_epf_bind() should be invoked when the EPF device has been bound to
210 a EPC device.
211
212*) pci_epf_unbind()
213
214 pci_epf_unbind() should be invoked when the binding between EPC device
215 and EPF device is lost.
diff --git a/Documentation/PCI/endpoint/pci-test-function.txt b/Documentation/PCI/endpoint/pci-test-function.txt
new file mode 100644
index 000000000000..0c519c9bf94a
--- /dev/null
+++ b/Documentation/PCI/endpoint/pci-test-function.txt
@@ -0,0 +1,66 @@
1 PCI TEST
2 Kishon Vijay Abraham I <kishon@ti.com>
3
4Traditionally PCI RC has always been validated by using standard
5PCI cards like ethernet PCI cards or USB PCI cards or SATA PCI cards.
6However with the addition of EP-core in linux kernel, it is possible
7to configure a PCI controller that can operate in EP mode to work as
8a test device.
9
10The PCI endpoint test device is a virtual device (defined in software)
11used to test the endpoint functionality and serve as a sample driver
12for other PCI endpoint devices (to use the EP framework).
13
14The PCI endpoint test device has the following registers:
15
16 1) PCI_ENDPOINT_TEST_MAGIC
17 2) PCI_ENDPOINT_TEST_COMMAND
18 3) PCI_ENDPOINT_TEST_STATUS
19 4) PCI_ENDPOINT_TEST_SRC_ADDR
20 5) PCI_ENDPOINT_TEST_DST_ADDR
21 6) PCI_ENDPOINT_TEST_SIZE
22 7) PCI_ENDPOINT_TEST_CHECKSUM
23
24*) PCI_ENDPOINT_TEST_MAGIC
25
26This register will be used to test BAR0. A known pattern will be written
27and read back from MAGIC register to verify BAR0.
28
29*) PCI_ENDPOINT_TEST_COMMAND:
30
31This register will be used by the host driver to indicate the function
32that the endpoint device must perform.
33
34Bitfield Description:
35 Bit 0 : raise legacy IRQ
36 Bit 1 : raise MSI IRQ
37 Bit 2 - 7 : MSI interrupt number
38 Bit 8 : read command (read data from RC buffer)
39 Bit 9 : write command (write data to RC buffer)
40 Bit 10 : copy command (copy data from one RC buffer to another
41 RC buffer)
42
43*) PCI_ENDPOINT_TEST_STATUS
44
45This register reflects the status of the PCI endpoint device.
46
47Bitfield Description:
48 Bit 0 : read success
49 Bit 1 : read fail
50 Bit 2 : write success
51 Bit 3 : write fail
52 Bit 4 : copy success
53 Bit 5 : copy fail
54 Bit 6 : IRQ raised
55 Bit 7 : source address is invalid
56 Bit 8 : destination address is invalid
57
58*) PCI_ENDPOINT_TEST_SRC_ADDR
59
60This register contains the source address (RC buffer address) for the
61COPY/READ command.
62
63*) PCI_ENDPOINT_TEST_DST_ADDR
64
65This register contains the destination address (RC buffer address) for
66the COPY/WRITE command.
diff --git a/Documentation/PCI/endpoint/pci-test-howto.txt b/Documentation/PCI/endpoint/pci-test-howto.txt
new file mode 100644
index 000000000000..75f48c3bb191
--- /dev/null
+++ b/Documentation/PCI/endpoint/pci-test-howto.txt
@@ -0,0 +1,179 @@
1 PCI TEST USERGUIDE
2 Kishon Vijay Abraham I <kishon@ti.com>
3
4This document is a guide to help users use pci-epf-test function driver
5and pci_endpoint_test host driver for testing PCI. The list of steps to
6be followed in the host side and EP side is given below.
7
81. Endpoint Device
9
101.1 Endpoint Controller Devices
11
12To find the list of endpoint controller devices in the system:
13
14 # ls /sys/class/pci_epc/
15 51000000.pcie_ep
16
17If PCI_ENDPOINT_CONFIGFS is enabled
18 # ls /sys/kernel/config/pci_ep/controllers
19 51000000.pcie_ep
20
211.2 Endpoint Function Drivers
22
23To find the list of endpoint function drivers in the system:
24
25 # ls /sys/bus/pci-epf/drivers
26 pci_epf_test
27
28If PCI_ENDPOINT_CONFIGFS is enabled
29 # ls /sys/kernel/config/pci_ep/functions
30 pci_epf_test
31
321.3 Creating pci-epf-test Device
33
34PCI endpoint function device can be created using the configfs. To create
35pci-epf-test device, the following commands can be used
36
37 # mount -t configfs none /sys/kernel/config
38 # cd /sys/kernel/config/pci_ep/
39 # mkdir functions/pci_epf_test/func1
40
41The "mkdir func1" above creates the pci-epf-test function device that will
42be probed by pci_epf_test driver.
43
44The PCI endpoint framework populates the directory with the following
45configurable fields.
46
47 # ls functions/pci_epf_test/func1
48 baseclass_code interrupt_pin revid subsys_vendor_id
49 cache_line_size msi_interrupts subclass_code vendorid
50 deviceid progif_code subsys_id
51
52The PCI endpoint function driver populates these entries with default values
53when the device is bound to the driver. The pci-epf-test driver populates
54vendorid with 0xffff and interrupt_pin with 0x0001
55
56 # cat functions/pci_epf_test/func1/vendorid
57 0xffff
58 # cat functions/pci_epf_test/func1/interrupt_pin
59 0x0001
60
611.4 Configuring pci-epf-test Device
62
63The user can configure the pci-epf-test device using configfs entry. In order
64to change the vendorid and the number of MSI interrupts used by the function
65device, the following commands can be used.
66
67 # echo 0x104c > functions/pci_epf_test/func1/vendorid
68 # echo 0xb500 > functions/pci_epf_test/func1/deviceid
69 # echo 16 > functions/pci_epf_test/func1/msi_interrupts
70
711.5 Binding pci-epf-test Device to EP Controller
72
73In order for the endpoint function device to be useful, it has to be bound to
74a PCI endpoint controller driver. Use the configfs to bind the function
75device to one of the controller driver present in the system.
76
77 # ln -s functions/pci_epf_test/func1 controllers/51000000.pcie_ep/
78
79Once the above step is completed, the PCI endpoint is ready to establish a link
80with the host.
81
821.6 Start the Link
83
84In order for the endpoint device to establish a link with the host, the _start_
85field should be populated with '1'.
86
87 # echo 1 > controllers/51000000.pcie_ep/start
88
892. RootComplex Device
90
912.1 lspci Output
92
93Note that the devices listed here correspond to the value populated in 1.4 above
94
95 00:00.0 PCI bridge: Texas Instruments Device 8888 (rev 01)
96 01:00.0 Unassigned class [ff00]: Texas Instruments Device b500
97
982.2 Using Endpoint Test function Device
99
100pcitest.sh added in tools/pci/ can be used to run all the default PCI endpoint
101tests. Before pcitest.sh can be used pcitest.c should be compiled using the
102following commands.
103
104 cd <kernel-dir>
105 make headers_install ARCH=arm
106 arm-linux-gnueabihf-gcc -Iusr/include tools/pci/pcitest.c -o pcitest
107 cp pcitest <rootfs>/usr/sbin/
108 cp tools/pci/pcitest.sh <rootfs>
109
1102.2.1 pcitest.sh Output
111 # ./pcitest.sh
112 BAR tests
113
114 BAR0: OKAY
115 BAR1: OKAY
116 BAR2: OKAY
117 BAR3: OKAY
118 BAR4: NOT OKAY
119 BAR5: NOT OKAY
120
121 Interrupt tests
122
123 LEGACY IRQ: NOT OKAY
124 MSI1: OKAY
125 MSI2: OKAY
126 MSI3: OKAY
127 MSI4: OKAY
128 MSI5: OKAY
129 MSI6: OKAY
130 MSI7: OKAY
131 MSI8: OKAY
132 MSI9: OKAY
133 MSI10: OKAY
134 MSI11: OKAY
135 MSI12: OKAY
136 MSI13: OKAY
137 MSI14: OKAY
138 MSI15: OKAY
139 MSI16: OKAY
140 MSI17: NOT OKAY
141 MSI18: NOT OKAY
142 MSI19: NOT OKAY
143 MSI20: NOT OKAY
144 MSI21: NOT OKAY
145 MSI22: NOT OKAY
146 MSI23: NOT OKAY
147 MSI24: NOT OKAY
148 MSI25: NOT OKAY
149 MSI26: NOT OKAY
150 MSI27: NOT OKAY
151 MSI28: NOT OKAY
152 MSI29: NOT OKAY
153 MSI30: NOT OKAY
154 MSI31: NOT OKAY
155 MSI32: NOT OKAY
156
157 Read Tests
158
159 READ ( 1 bytes): OKAY
160 READ ( 1024 bytes): OKAY
161 READ ( 1025 bytes): OKAY
162 READ (1024000 bytes): OKAY
163 READ (1024001 bytes): OKAY
164
165 Write Tests
166
167 WRITE ( 1 bytes): OKAY
168 WRITE ( 1024 bytes): OKAY
169 WRITE ( 1025 bytes): OKAY
170 WRITE (1024000 bytes): OKAY
171 WRITE (1024001 bytes): OKAY
172
173 Copy Tests
174
175 COPY ( 1 bytes): OKAY
176 COPY ( 1024 bytes): OKAY
177 COPY ( 1025 bytes): OKAY
178 COPY (1024000 bytes): OKAY
179 COPY (1024001 bytes): OKAY
diff --git a/Documentation/devicetree/bindings/pci/designware-pcie.txt b/Documentation/devicetree/bindings/pci/designware-pcie.txt
index 1392c705ceca..b2480dd38c11 100644
--- a/Documentation/devicetree/bindings/pci/designware-pcie.txt
+++ b/Documentation/devicetree/bindings/pci/designware-pcie.txt
@@ -6,30 +6,40 @@ Required properties:
6- reg-names: Must be "config" for the PCIe configuration space. 6- reg-names: Must be "config" for the PCIe configuration space.
7 (The old way of getting the configuration address space from "ranges" 7 (The old way of getting the configuration address space from "ranges"
8 is deprecated and should be avoided.) 8 is deprecated and should be avoided.)
9- num-lanes: number of lanes to use
10RC mode:
9- #address-cells: set to <3> 11- #address-cells: set to <3>
10- #size-cells: set to <2> 12- #size-cells: set to <2>
11- device_type: set to "pci" 13- device_type: set to "pci"
12- ranges: ranges for the PCI memory and I/O regions 14- ranges: ranges for the PCI memory and I/O regions
13- #interrupt-cells: set to <1> 15- #interrupt-cells: set to <1>
14- interrupt-map-mask and interrupt-map: standard PCI properties 16- interrupt-map-mask and interrupt-map: standard PCI
15 to define the mapping of the PCIe interface to interrupt 17 properties to define the mapping of the PCIe interface to interrupt
16 numbers. 18 numbers.
17- num-lanes: number of lanes to use 19EP mode:
20- num-ib-windows: number of inbound address translation
21 windows
22- num-ob-windows: number of outbound address translation
23 windows
18 24
19Optional properties: 25Optional properties:
20- num-viewport: number of view ports configured in hardware. If a platform
21 does not specify it, the driver assumes 2.
22- num-lanes: number of lanes to use (this property should be specified unless 26- num-lanes: number of lanes to use (this property should be specified unless
23 the link is brought already up in BIOS) 27 the link is brought already up in BIOS)
24- reset-gpio: gpio pin number of power good signal 28- reset-gpio: gpio pin number of power good signal
25- bus-range: PCI bus numbers covered (it is recommended for new devicetrees to
26 specify this property, to keep backwards compatibility a range of 0x00-0xff
27 is assumed if not present)
28- clocks: Must contain an entry for each entry in clock-names. 29- clocks: Must contain an entry for each entry in clock-names.
29 See ../clocks/clock-bindings.txt for details. 30 See ../clocks/clock-bindings.txt for details.
30- clock-names: Must include the following entries: 31- clock-names: Must include the following entries:
31 - "pcie" 32 - "pcie"
32 - "pcie_bus" 33 - "pcie_bus"
34RC mode:
35- num-viewport: number of view ports configured in
36 hardware. If a platform does not specify it, the driver assumes 2.
37- bus-range: PCI bus numbers covered (it is recommended
38 for new devicetrees to specify this property, to keep backwards
39 compatibility a range of 0x00-0xff is assumed if not present)
40EP mode:
41- max-functions: maximum number of functions that can be
42 configured
33 43
34Example configuration: 44Example configuration:
35 45
diff --git a/Documentation/devicetree/bindings/pci/ti-pci.txt b/Documentation/devicetree/bindings/pci/ti-pci.txt
index 60e25161f351..6a07c96227e0 100644
--- a/Documentation/devicetree/bindings/pci/ti-pci.txt
+++ b/Documentation/devicetree/bindings/pci/ti-pci.txt
@@ -1,17 +1,22 @@
1TI PCI Controllers 1TI PCI Controllers
2 2
3PCIe Designware Controller 3PCIe Designware Controller
4 - compatible: Should be "ti,dra7-pcie"" 4 - compatible: Should be "ti,dra7-pcie" for RC
5 - reg : Two register ranges as listed in the reg-names property 5 Should be "ti,dra7-pcie-ep" for EP
6 - reg-names : The first entry must be "ti-conf" for the TI specific registers
7 The second entry must be "rc-dbics" for the designware pcie
8 registers
9 The third entry must be "config" for the PCIe configuration space
10 - phys : list of PHY specifiers (used by generic PHY framework) 6 - phys : list of PHY specifiers (used by generic PHY framework)
11 - phy-names : must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the 7 - phy-names : must be "pcie-phy0", "pcie-phy1", "pcie-phyN".. based on the
12 number of PHYs as specified in *phys* property. 8 number of PHYs as specified in *phys* property.
13 - ti,hwmods : Name of the hwmod associated to the pcie, "pcie<X>", 9 - ti,hwmods : Name of the hwmod associated to the pcie, "pcie<X>",
14 where <X> is the instance number of the pcie from the HW spec. 10 where <X> is the instance number of the pcie from the HW spec.
11 - num-lanes as specified in ../designware-pcie.txt
12
13HOST MODE
14=========
15 - reg : Two register ranges as listed in the reg-names property
16 - reg-names : The first entry must be "ti-conf" for the TI specific registers
17 The second entry must be "rc-dbics" for the DesignWare PCIe
18 registers
19 The third entry must be "config" for the PCIe configuration space
15 - interrupts : Two interrupt entries must be specified. The first one is for 20 - interrupts : Two interrupt entries must be specified. The first one is for
16 main interrupt line and the second for MSI interrupt line. 21 main interrupt line and the second for MSI interrupt line.
17 - #address-cells, 22 - #address-cells,
@@ -19,13 +24,36 @@ PCIe Designware Controller
19 #interrupt-cells, 24 #interrupt-cells,
20 device_type, 25 device_type,
21 ranges, 26 ranges,
22 num-lanes,
23 interrupt-map-mask, 27 interrupt-map-mask,
24 interrupt-map : as specified in ../designware-pcie.txt 28 interrupt-map : as specified in ../designware-pcie.txt
25 29
30DEVICE MODE
31===========
32 - reg : Four register ranges as listed in the reg-names property
33 - reg-names : "ti-conf" for the TI specific registers
34 "ep_dbics" for the standard configuration registers as
35 they are locally accessed within the DIF CS space
36 "ep_dbics2" for the standard configuration registers as
37 they are locally accessed within the DIF CS2 space
38 "addr_space" used to map remote RC address space
39 - interrupts : one interrupt entries must be specified for main interrupt.
40 - num-ib-windows : number of inbound address translation windows
41 - num-ob-windows : number of outbound address translation windows
42 - ti,syscon-unaligned-access: phandle to the syscon DT node. The 1st argument
43 should contain the register offset within syscon
44 and the 2nd argument should contain the bit field
45 for setting the bit to enable unaligned
46 access.
47
26Optional Property: 48Optional Property:
27 - gpios : Should be added if a gpio line is required to drive PERST# line 49 - gpios : Should be added if a gpio line is required to drive PERST# line
28 50
51NOTE: Two DT nodes may be added for each PCI controller; one for host
52mode and another for device mode. So in order for PCI to
53work in host mode, EP mode DT node should be disabled and in order to PCI to
54work in EP mode, host mode DT node should be disabled. Host mode and EP
55mode are mutually exclusive.
56
29Example: 57Example:
30axi { 58axi {
31 compatible = "simple-bus"; 59 compatible = "simple-bus";
diff --git a/Documentation/misc-devices/pci-endpoint-test.txt b/Documentation/misc-devices/pci-endpoint-test.txt
new file mode 100644
index 000000000000..4ebc3594b32c
--- /dev/null
+++ b/Documentation/misc-devices/pci-endpoint-test.txt
@@ -0,0 +1,35 @@
1Driver for PCI Endpoint Test Function
2
3This driver should be used as a host side driver if the root complex is
4connected to a configurable PCI endpoint running *pci_epf_test* function
5driver configured according to [1].
6
7The "pci_endpoint_test" driver can be used to perform the following tests.
8
9The PCI driver for the test device performs the following tests
10 *) verifying addresses programmed in BAR
11 *) raise legacy IRQ
12 *) raise MSI IRQ
13 *) read data
14 *) write data
15 *) copy data
16
17This misc driver creates /dev/pci-endpoint-test.<num> for every
18*pci_epf_test* function connected to the root complex and "ioctls"
19should be used to perform the above tests.
20
21ioctl
22-----
23 PCITEST_BAR: Tests the BAR. The number of the BAR to be tested
24 should be passed as argument.
25 PCITEST_LEGACY_IRQ: Tests legacy IRQ
26 PCITEST_MSI: Tests message signalled interrupts. The MSI number
27 to be tested should be passed as argument.
28 PCITEST_WRITE: Perform write tests. The size of the buffer should be passed
29 as argument.
30 PCITEST_READ: Perform read tests. The size of the buffer should be passed
31 as argument.
32 PCITEST_COPY: Perform read tests. The size of the buffer should be passed
33 as argument.
34
35[1] -> Documentation/PCI/endpoint/function/binding/pci-test.txt
diff --git a/MAINTAINERS b/MAINTAINERS
index c265a5fe4848..15ed84389092 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -9581,6 +9581,15 @@ F: include/linux/pci*
9581F: arch/x86/pci/ 9581F: arch/x86/pci/
9582F: arch/x86/kernel/quirks.c 9582F: arch/x86/kernel/quirks.c
9583 9583
9584PCI ENDPOINT SUBSYSTEM
9585M: Kishon Vijay Abraham I <kishon@ti.com>
9586L: linux-pci@vger.kernel.org
9587T: git git://git.kernel.org/pub/scm/linux/kernel/git/kishon/pci-endpoint.git
9588S: Supported
9589F: drivers/pci/endpoint/
9590F: drivers/misc/pci_endpoint_test.c
9591F: tools/pci/
9592
9584PCI DRIVER FOR ALTERA PCIE IP 9593PCI DRIVER FOR ALTERA PCIE IP
9585M: Ley Foon Tan <lftan@altera.com> 9594M: Ley Foon Tan <lftan@altera.com>
9586L: rfi@lists.rocketboards.org (moderated for non-subscribers) 9595L: rfi@lists.rocketboards.org (moderated for non-subscribers)
diff --git a/arch/arm/mach-omap2/clockdomains7xx_data.c b/arch/arm/mach-omap2/clockdomains7xx_data.c
index 6c679659cda5..67ebff829cf2 100644
--- a/arch/arm/mach-omap2/clockdomains7xx_data.c
+++ b/arch/arm/mach-omap2/clockdomains7xx_data.c
@@ -524,7 +524,7 @@ static struct clockdomain pcie_7xx_clkdm = {
524 .dep_bit = DRA7XX_PCIE_STATDEP_SHIFT, 524 .dep_bit = DRA7XX_PCIE_STATDEP_SHIFT,
525 .wkdep_srcs = pcie_wkup_sleep_deps, 525 .wkdep_srcs = pcie_wkup_sleep_deps,
526 .sleepdep_srcs = pcie_wkup_sleep_deps, 526 .sleepdep_srcs = pcie_wkup_sleep_deps,
527 .flags = CLKDM_CAN_HWSUP_SWSUP, 527 .flags = CLKDM_CAN_SWSUP,
528}; 528};
529 529
530static struct clockdomain atl_7xx_clkdm = { 530static struct clockdomain atl_7xx_clkdm = {
diff --git a/drivers/Makefile b/drivers/Makefile
index 2eced9afba53..a5f8e43b2c4d 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -14,7 +14,9 @@ obj-$(CONFIG_GENERIC_PHY) += phy/
14obj-$(CONFIG_PINCTRL) += pinctrl/ 14obj-$(CONFIG_PINCTRL) += pinctrl/
15obj-$(CONFIG_GPIOLIB) += gpio/ 15obj-$(CONFIG_GPIOLIB) += gpio/
16obj-y += pwm/ 16obj-y += pwm/
17
17obj-$(CONFIG_PCI) += pci/ 18obj-$(CONFIG_PCI) += pci/
19obj-$(CONFIG_PCI_ENDPOINT) += pci/endpoint/
18# PCI dwc controller drivers 20# PCI dwc controller drivers
19obj-y += pci/dwc/ 21obj-y += pci/dwc/
20 22
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index c290990d73ed..527b115c4e23 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -771,6 +771,13 @@ config PANEL_BOOT_MESSAGE
771 771
772endif # PANEL 772endif # PANEL
773 773
774config PCI_ENDPOINT_TEST
775 depends on PCI
776 tristate "PCI Endpoint Test driver"
777 ---help---
778 Enable this configuration option to enable the host side test driver
779 for PCI Endpoint.
780
774source "drivers/misc/c2port/Kconfig" 781source "drivers/misc/c2port/Kconfig"
775source "drivers/misc/eeprom/Kconfig" 782source "drivers/misc/eeprom/Kconfig"
776source "drivers/misc/cb710/Kconfig" 783source "drivers/misc/cb710/Kconfig"
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 7a3ea89339b4..6e139cd70421 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -54,6 +54,7 @@ obj-$(CONFIG_ECHO) += echo/
54obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o 54obj-$(CONFIG_VEXPRESS_SYSCFG) += vexpress-syscfg.o
55obj-$(CONFIG_CXL_BASE) += cxl/ 55obj-$(CONFIG_CXL_BASE) += cxl/
56obj-$(CONFIG_PANEL) += panel.o 56obj-$(CONFIG_PANEL) += panel.o
57obj-$(CONFIG_PCI_ENDPOINT_TEST) += pci_endpoint_test.o
57 58
58lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o 59lkdtm-$(CONFIG_LKDTM) += lkdtm_core.o
59lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o 60lkdtm-$(CONFIG_LKDTM) += lkdtm_bugs.o
diff --git a/drivers/misc/pci_endpoint_test.c b/drivers/misc/pci_endpoint_test.c
new file mode 100644
index 000000000000..09c10f426b64
--- /dev/null
+++ b/drivers/misc/pci_endpoint_test.c
@@ -0,0 +1,534 @@
1/**
2 * Host side test driver to test endpoint functionality
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/crc32.h>
21#include <linux/delay.h>
22#include <linux/fs.h>
23#include <linux/io.h>
24#include <linux/interrupt.h>
25#include <linux/irq.h>
26#include <linux/miscdevice.h>
27#include <linux/module.h>
28#include <linux/mutex.h>
29#include <linux/random.h>
30#include <linux/slab.h>
31#include <linux/pci.h>
32#include <linux/pci_ids.h>
33
34#include <linux/pci_regs.h>
35
36#include <uapi/linux/pcitest.h>
37
38#define DRV_MODULE_NAME "pci-endpoint-test"
39
40#define PCI_ENDPOINT_TEST_MAGIC 0x0
41
42#define PCI_ENDPOINT_TEST_COMMAND 0x4
43#define COMMAND_RAISE_LEGACY_IRQ BIT(0)
44#define COMMAND_RAISE_MSI_IRQ BIT(1)
45#define MSI_NUMBER_SHIFT 2
46/* 6 bits for MSI number */
47#define COMMAND_READ BIT(8)
48#define COMMAND_WRITE BIT(9)
49#define COMMAND_COPY BIT(10)
50
51#define PCI_ENDPOINT_TEST_STATUS 0x8
52#define STATUS_READ_SUCCESS BIT(0)
53#define STATUS_READ_FAIL BIT(1)
54#define STATUS_WRITE_SUCCESS BIT(2)
55#define STATUS_WRITE_FAIL BIT(3)
56#define STATUS_COPY_SUCCESS BIT(4)
57#define STATUS_COPY_FAIL BIT(5)
58#define STATUS_IRQ_RAISED BIT(6)
59#define STATUS_SRC_ADDR_INVALID BIT(7)
60#define STATUS_DST_ADDR_INVALID BIT(8)
61
62#define PCI_ENDPOINT_TEST_LOWER_SRC_ADDR 0xc
63#define PCI_ENDPOINT_TEST_UPPER_SRC_ADDR 0x10
64
65#define PCI_ENDPOINT_TEST_LOWER_DST_ADDR 0x14
66#define PCI_ENDPOINT_TEST_UPPER_DST_ADDR 0x18
67
68#define PCI_ENDPOINT_TEST_SIZE 0x1c
69#define PCI_ENDPOINT_TEST_CHECKSUM 0x20
70
71static DEFINE_IDA(pci_endpoint_test_ida);
72
73#define to_endpoint_test(priv) container_of((priv), struct pci_endpoint_test, \
74 miscdev)
75enum pci_barno {
76 BAR_0,
77 BAR_1,
78 BAR_2,
79 BAR_3,
80 BAR_4,
81 BAR_5,
82};
83
84struct pci_endpoint_test {
85 struct pci_dev *pdev;
86 void __iomem *base;
87 void __iomem *bar[6];
88 struct completion irq_raised;
89 int last_irq;
90 /* mutex to protect the ioctls */
91 struct mutex mutex;
92 struct miscdevice miscdev;
93};
94
95static int bar_size[] = { 4, 512, 1024, 16384, 131072, 1048576 };
96
97static inline u32 pci_endpoint_test_readl(struct pci_endpoint_test *test,
98 u32 offset)
99{
100 return readl(test->base + offset);
101}
102
103static inline void pci_endpoint_test_writel(struct pci_endpoint_test *test,
104 u32 offset, u32 value)
105{
106 writel(value, test->base + offset);
107}
108
109static inline u32 pci_endpoint_test_bar_readl(struct pci_endpoint_test *test,
110 int bar, int offset)
111{
112 return readl(test->bar[bar] + offset);
113}
114
115static inline void pci_endpoint_test_bar_writel(struct pci_endpoint_test *test,
116 int bar, u32 offset, u32 value)
117{
118 writel(value, test->bar[bar] + offset);
119}
120
121static irqreturn_t pci_endpoint_test_irqhandler(int irq, void *dev_id)
122{
123 struct pci_endpoint_test *test = dev_id;
124 u32 reg;
125
126 reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
127 if (reg & STATUS_IRQ_RAISED) {
128 test->last_irq = irq;
129 complete(&test->irq_raised);
130 reg &= ~STATUS_IRQ_RAISED;
131 }
132 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_STATUS,
133 reg);
134
135 return IRQ_HANDLED;
136}
137
138static bool pci_endpoint_test_bar(struct pci_endpoint_test *test,
139 enum pci_barno barno)
140{
141 int j;
142 u32 val;
143 int size;
144
145 if (!test->bar[barno])
146 return false;
147
148 size = bar_size[barno];
149
150 for (j = 0; j < size; j += 4)
151 pci_endpoint_test_bar_writel(test, barno, j, 0xA0A0A0A0);
152
153 for (j = 0; j < size; j += 4) {
154 val = pci_endpoint_test_bar_readl(test, barno, j);
155 if (val != 0xA0A0A0A0)
156 return false;
157 }
158
159 return true;
160}
161
162static bool pci_endpoint_test_legacy_irq(struct pci_endpoint_test *test)
163{
164 u32 val;
165
166 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
167 COMMAND_RAISE_LEGACY_IRQ);
168 val = wait_for_completion_timeout(&test->irq_raised,
169 msecs_to_jiffies(1000));
170 if (!val)
171 return false;
172
173 return true;
174}
175
176static bool pci_endpoint_test_msi_irq(struct pci_endpoint_test *test,
177 u8 msi_num)
178{
179 u32 val;
180 struct pci_dev *pdev = test->pdev;
181
182 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
183 msi_num << MSI_NUMBER_SHIFT |
184 COMMAND_RAISE_MSI_IRQ);
185 val = wait_for_completion_timeout(&test->irq_raised,
186 msecs_to_jiffies(1000));
187 if (!val)
188 return false;
189
190 if (test->last_irq - pdev->irq == msi_num - 1)
191 return true;
192
193 return false;
194}
195
196static bool pci_endpoint_test_copy(struct pci_endpoint_test *test, size_t size)
197{
198 bool ret = false;
199 void *src_addr;
200 void *dst_addr;
201 dma_addr_t src_phys_addr;
202 dma_addr_t dst_phys_addr;
203 struct pci_dev *pdev = test->pdev;
204 struct device *dev = &pdev->dev;
205 u32 src_crc32;
206 u32 dst_crc32;
207
208 src_addr = dma_alloc_coherent(dev, size, &src_phys_addr, GFP_KERNEL);
209 if (!src_addr) {
210 dev_err(dev, "failed to allocate source buffer\n");
211 ret = false;
212 goto err;
213 }
214
215 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
216 lower_32_bits(src_phys_addr));
217
218 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
219 upper_32_bits(src_phys_addr));
220
221 get_random_bytes(src_addr, size);
222 src_crc32 = crc32_le(~0, src_addr, size);
223
224 dst_addr = dma_alloc_coherent(dev, size, &dst_phys_addr, GFP_KERNEL);
225 if (!dst_addr) {
226 dev_err(dev, "failed to allocate destination address\n");
227 ret = false;
228 goto err_src_addr;
229 }
230
231 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
232 lower_32_bits(dst_phys_addr));
233 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
234 upper_32_bits(dst_phys_addr));
235
236 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE,
237 size);
238
239 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
240 1 << MSI_NUMBER_SHIFT | COMMAND_COPY);
241
242 wait_for_completion(&test->irq_raised);
243
244 dst_crc32 = crc32_le(~0, dst_addr, size);
245 if (dst_crc32 == src_crc32)
246 ret = true;
247
248 dma_free_coherent(dev, size, dst_addr, dst_phys_addr);
249
250err_src_addr:
251 dma_free_coherent(dev, size, src_addr, src_phys_addr);
252
253err:
254 return ret;
255}
256
257static bool pci_endpoint_test_write(struct pci_endpoint_test *test, size_t size)
258{
259 bool ret = false;
260 u32 reg;
261 void *addr;
262 dma_addr_t phys_addr;
263 struct pci_dev *pdev = test->pdev;
264 struct device *dev = &pdev->dev;
265 u32 crc32;
266
267 addr = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL);
268 if (!addr) {
269 dev_err(dev, "failed to allocate address\n");
270 ret = false;
271 goto err;
272 }
273
274 get_random_bytes(addr, size);
275
276 crc32 = crc32_le(~0, addr, size);
277 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_CHECKSUM,
278 crc32);
279
280 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_SRC_ADDR,
281 lower_32_bits(phys_addr));
282 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_SRC_ADDR,
283 upper_32_bits(phys_addr));
284
285 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
286
287 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
288 1 << MSI_NUMBER_SHIFT | COMMAND_READ);
289
290 wait_for_completion(&test->irq_raised);
291
292 reg = pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_STATUS);
293 if (reg & STATUS_READ_SUCCESS)
294 ret = true;
295
296 dma_free_coherent(dev, size, addr, phys_addr);
297
298err:
299 return ret;
300}
301
302static bool pci_endpoint_test_read(struct pci_endpoint_test *test, size_t size)
303{
304 bool ret = false;
305 void *addr;
306 dma_addr_t phys_addr;
307 struct pci_dev *pdev = test->pdev;
308 struct device *dev = &pdev->dev;
309 u32 crc32;
310
311 addr = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL);
312 if (!addr) {
313 dev_err(dev, "failed to allocate destination address\n");
314 ret = false;
315 goto err;
316 }
317
318 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_LOWER_DST_ADDR,
319 lower_32_bits(phys_addr));
320 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_UPPER_DST_ADDR,
321 upper_32_bits(phys_addr));
322
323 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_SIZE, size);
324
325 pci_endpoint_test_writel(test, PCI_ENDPOINT_TEST_COMMAND,
326 1 << MSI_NUMBER_SHIFT | COMMAND_WRITE);
327
328 wait_for_completion(&test->irq_raised);
329
330 crc32 = crc32_le(~0, addr, size);
331 if (crc32 == pci_endpoint_test_readl(test, PCI_ENDPOINT_TEST_CHECKSUM))
332 ret = true;
333
334 dma_free_coherent(dev, size, addr, phys_addr);
335err:
336 return ret;
337}
338
339static long pci_endpoint_test_ioctl(struct file *file, unsigned int cmd,
340 unsigned long arg)
341{
342 int ret = -EINVAL;
343 enum pci_barno bar;
344 struct pci_endpoint_test *test = to_endpoint_test(file->private_data);
345
346 mutex_lock(&test->mutex);
347 switch (cmd) {
348 case PCITEST_BAR:
349 bar = arg;
350 if (bar < 0 || bar > 5)
351 goto ret;
352 ret = pci_endpoint_test_bar(test, bar);
353 break;
354 case PCITEST_LEGACY_IRQ:
355 ret = pci_endpoint_test_legacy_irq(test);
356 break;
357 case PCITEST_MSI:
358 ret = pci_endpoint_test_msi_irq(test, arg);
359 break;
360 case PCITEST_WRITE:
361 ret = pci_endpoint_test_write(test, arg);
362 break;
363 case PCITEST_READ:
364 ret = pci_endpoint_test_read(test, arg);
365 break;
366 case PCITEST_COPY:
367 ret = pci_endpoint_test_copy(test, arg);
368 break;
369 }
370
371ret:
372 mutex_unlock(&test->mutex);
373 return ret;
374}
375
376static const struct file_operations pci_endpoint_test_fops = {
377 .owner = THIS_MODULE,
378 .unlocked_ioctl = pci_endpoint_test_ioctl,
379};
380
381static int pci_endpoint_test_probe(struct pci_dev *pdev,
382 const struct pci_device_id *ent)
383{
384 int i;
385 int err;
386 int irq;
387 int id;
388 char name[20];
389 enum pci_barno bar;
390 void __iomem *base;
391 struct device *dev = &pdev->dev;
392 struct pci_endpoint_test *test;
393 struct miscdevice *misc_device;
394
395 if (pci_is_bridge(pdev))
396 return -ENODEV;
397
398 test = devm_kzalloc(dev, sizeof(*test), GFP_KERNEL);
399 if (!test)
400 return -ENOMEM;
401
402 test->pdev = pdev;
403 init_completion(&test->irq_raised);
404 mutex_init(&test->mutex);
405
406 err = pci_enable_device(pdev);
407 if (err) {
408 dev_err(dev, "Cannot enable PCI device\n");
409 return err;
410 }
411
412 err = pci_request_regions(pdev, DRV_MODULE_NAME);
413 if (err) {
414 dev_err(dev, "Cannot obtain PCI resources\n");
415 goto err_disable_pdev;
416 }
417
418 pci_set_master(pdev);
419
420 irq = pci_alloc_irq_vectors(pdev, 1, 32, PCI_IRQ_MSI);
421 if (irq < 0)
422 dev_err(dev, "failed to get MSI interrupts\n");
423
424 err = devm_request_irq(dev, pdev->irq, pci_endpoint_test_irqhandler,
425 IRQF_SHARED, DRV_MODULE_NAME, test);
426 if (err) {
427 dev_err(dev, "failed to request IRQ %d\n", pdev->irq);
428 goto err_disable_msi;
429 }
430
431 for (i = 1; i < irq; i++) {
432 err = devm_request_irq(dev, pdev->irq + i,
433 pci_endpoint_test_irqhandler,
434 IRQF_SHARED, DRV_MODULE_NAME, test);
435 if (err)
436 dev_err(dev, "failed to request IRQ %d for MSI %d\n",
437 pdev->irq + i, i + 1);
438 }
439
440 for (bar = BAR_0; bar <= BAR_5; bar++) {
441 base = pci_ioremap_bar(pdev, bar);
442 if (!base) {
443 dev_err(dev, "failed to read BAR%d\n", bar);
444 WARN_ON(bar == BAR_0);
445 }
446 test->bar[bar] = base;
447 }
448
449 test->base = test->bar[0];
450 if (!test->base) {
451 dev_err(dev, "Cannot perform PCI test without BAR0\n");
452 goto err_iounmap;
453 }
454
455 pci_set_drvdata(pdev, test);
456
457 id = ida_simple_get(&pci_endpoint_test_ida, 0, 0, GFP_KERNEL);
458 if (id < 0) {
459 dev_err(dev, "unable to get id\n");
460 goto err_iounmap;
461 }
462
463 snprintf(name, sizeof(name), DRV_MODULE_NAME ".%d", id);
464 misc_device = &test->miscdev;
465 misc_device->minor = MISC_DYNAMIC_MINOR;
466 misc_device->name = name;
467 misc_device->fops = &pci_endpoint_test_fops,
468
469 err = misc_register(misc_device);
470 if (err) {
471 dev_err(dev, "failed to register device\n");
472 goto err_ida_remove;
473 }
474
475 return 0;
476
477err_ida_remove:
478 ida_simple_remove(&pci_endpoint_test_ida, id);
479
480err_iounmap:
481 for (bar = BAR_0; bar <= BAR_5; bar++) {
482 if (test->bar[bar])
483 pci_iounmap(pdev, test->bar[bar]);
484 }
485
486err_disable_msi:
487 pci_disable_msi(pdev);
488 pci_release_regions(pdev);
489
490err_disable_pdev:
491 pci_disable_device(pdev);
492
493 return err;
494}
495
496static void pci_endpoint_test_remove(struct pci_dev *pdev)
497{
498 int id;
499 enum pci_barno bar;
500 struct pci_endpoint_test *test = pci_get_drvdata(pdev);
501 struct miscdevice *misc_device = &test->miscdev;
502
503 if (sscanf(misc_device->name, DRV_MODULE_NAME ".%d", &id) != 1)
504 return;
505
506 misc_deregister(&test->miscdev);
507 ida_simple_remove(&pci_endpoint_test_ida, id);
508 for (bar = BAR_0; bar <= BAR_5; bar++) {
509 if (test->bar[bar])
510 pci_iounmap(pdev, test->bar[bar]);
511 }
512 pci_disable_msi(pdev);
513 pci_release_regions(pdev);
514 pci_disable_device(pdev);
515}
516
517static const struct pci_device_id pci_endpoint_test_tbl[] = {
518 { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA74x) },
519 { PCI_DEVICE(PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_DRA72x) },
520 { }
521};
522MODULE_DEVICE_TABLE(pci, pci_endpoint_test_tbl);
523
524static struct pci_driver pci_endpoint_test_driver = {
525 .name = DRV_MODULE_NAME,
526 .id_table = pci_endpoint_test_tbl,
527 .probe = pci_endpoint_test_probe,
528 .remove = pci_endpoint_test_remove,
529};
530module_pci_driver(pci_endpoint_test_driver);
531
532MODULE_DESCRIPTION("PCI ENDPOINT TEST HOST DRIVER");
533MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
534MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index df141420c902..9747c1ec8c74 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -134,3 +134,4 @@ config PCI_HYPERV
134source "drivers/pci/hotplug/Kconfig" 134source "drivers/pci/hotplug/Kconfig"
135source "drivers/pci/dwc/Kconfig" 135source "drivers/pci/dwc/Kconfig"
136source "drivers/pci/host/Kconfig" 136source "drivers/pci/host/Kconfig"
137source "drivers/pci/endpoint/Kconfig"
diff --git a/drivers/pci/dwc/Kconfig b/drivers/pci/dwc/Kconfig
index dfb8a69afc28..b7e15526d676 100644
--- a/drivers/pci/dwc/Kconfig
+++ b/drivers/pci/dwc/Kconfig
@@ -9,16 +9,44 @@ config PCIE_DW_HOST
9 depends on PCI_MSI_IRQ_DOMAIN 9 depends on PCI_MSI_IRQ_DOMAIN
10 select PCIE_DW 10 select PCIE_DW
11 11
12config PCIE_DW_EP
13 bool
14 depends on PCI_ENDPOINT
15 select PCIE_DW
16
12config PCI_DRA7XX 17config PCI_DRA7XX
13 bool "TI DRA7xx PCIe controller" 18 bool "TI DRA7xx PCIe controller"
14 depends on PCI 19 depends on (PCI && PCI_MSI_IRQ_DOMAIN) || PCI_ENDPOINT
15 depends on OF && HAS_IOMEM && TI_PIPE3 20 depends on OF && HAS_IOMEM && TI_PIPE3
21 help
22 Enables support for the PCIe controller in the DRA7xx SoC. There
23 are two instances of PCIe controller in DRA7xx. This controller can
24 work either as EP or RC. In order to enable host-specific features
25 PCI_DRA7XX_HOST must be selected and in order to enable device-
26 specific features PCI_DRA7XX_EP must be selected. This uses
27 the Designware core.
28
29if PCI_DRA7XX
30
31config PCI_DRA7XX_HOST
32 bool "PCI DRA7xx Host Mode"
33 depends on PCI
16 depends on PCI_MSI_IRQ_DOMAIN 34 depends on PCI_MSI_IRQ_DOMAIN
17 select PCIE_DW_HOST 35 select PCIE_DW_HOST
36 default y
18 help 37 help
19 Enables support for the PCIe controller in the DRA7xx SoC. There 38 Enables support for the PCIe controller in the DRA7xx SoC to work in
20 are two instances of PCIe controller in DRA7xx. This controller can 39 host mode.
21 act both as EP and RC. This reuses the Designware core. 40
41config PCI_DRA7XX_EP
42 bool "PCI DRA7xx Endpoint Mode"
43 depends on PCI_ENDPOINT
44 select PCIE_DW_EP
45 help
46 Enables support for the PCIe controller in the DRA7xx SoC to work in
47 endpoint mode.
48
49endif
22 50
23config PCIE_DW_PLAT 51config PCIE_DW_PLAT
24 bool "Platform bus based DesignWare PCIe Controller" 52 bool "Platform bus based DesignWare PCIe Controller"
@@ -89,6 +117,7 @@ config PCI_HISI
89 depends on PCI_MSI_IRQ_DOMAIN 117 depends on PCI_MSI_IRQ_DOMAIN
90 select PCIEPORTBUS 118 select PCIEPORTBUS
91 select PCIE_DW_HOST 119 select PCIE_DW_HOST
120 select PCI_HOST_COMMON
92 help 121 help
93 Say Y here if you want PCIe controller support on HiSilicon 122 Say Y here if you want PCIe controller support on HiSilicon
94 Hip05 and Hip06 SoCs 123 Hip05 and Hip06 SoCs
diff --git a/drivers/pci/dwc/Makefile b/drivers/pci/dwc/Makefile
index a2df13c28798..f31a8596442a 100644
--- a/drivers/pci/dwc/Makefile
+++ b/drivers/pci/dwc/Makefile
@@ -1,7 +1,10 @@
1obj-$(CONFIG_PCIE_DW) += pcie-designware.o 1obj-$(CONFIG_PCIE_DW) += pcie-designware.o
2obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o 2obj-$(CONFIG_PCIE_DW_HOST) += pcie-designware-host.o
3obj-$(CONFIG_PCIE_DW_EP) += pcie-designware-ep.o
3obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o 4obj-$(CONFIG_PCIE_DW_PLAT) += pcie-designware-plat.o
4obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o 5ifneq ($(filter y,$(CONFIG_PCI_DRA7XX_HOST) $(CONFIG_PCI_DRA7XX_EP)),)
6 obj-$(CONFIG_PCI_DRA7XX) += pci-dra7xx.o
7endif
5obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o 8obj-$(CONFIG_PCI_EXYNOS) += pci-exynos.o
6obj-$(CONFIG_PCI_IMX6) += pci-imx6.o 9obj-$(CONFIG_PCI_IMX6) += pci-imx6.o
7obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o 10obj-$(CONFIG_PCIE_SPEAR13XX) += pcie-spear13xx.o
diff --git a/drivers/pci/dwc/pci-dra7xx.c b/drivers/pci/dwc/pci-dra7xx.c
index 0984baff07e3..8decf46cf525 100644
--- a/drivers/pci/dwc/pci-dra7xx.c
+++ b/drivers/pci/dwc/pci-dra7xx.c
@@ -10,12 +10,14 @@
10 * published by the Free Software Foundation. 10 * published by the Free Software Foundation.
11 */ 11 */
12 12
13#include <linux/delay.h>
13#include <linux/err.h> 14#include <linux/err.h>
14#include <linux/interrupt.h> 15#include <linux/interrupt.h>
15#include <linux/irq.h> 16#include <linux/irq.h>
16#include <linux/irqdomain.h> 17#include <linux/irqdomain.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
18#include <linux/init.h> 19#include <linux/init.h>
20#include <linux/of_device.h>
19#include <linux/of_gpio.h> 21#include <linux/of_gpio.h>
20#include <linux/of_pci.h> 22#include <linux/of_pci.h>
21#include <linux/pci.h> 23#include <linux/pci.h>
@@ -24,6 +26,8 @@
24#include <linux/pm_runtime.h> 26#include <linux/pm_runtime.h>
25#include <linux/resource.h> 27#include <linux/resource.h>
26#include <linux/types.h> 28#include <linux/types.h>
29#include <linux/mfd/syscon.h>
30#include <linux/regmap.h>
27 31
28#include "pcie-designware.h" 32#include "pcie-designware.h"
29 33
@@ -57,6 +61,11 @@
57#define MSI BIT(4) 61#define MSI BIT(4)
58#define LEG_EP_INTERRUPTS (INTA | INTB | INTC | INTD) 62#define LEG_EP_INTERRUPTS (INTA | INTB | INTC | INTD)
59 63
64#define PCIECTRL_TI_CONF_DEVICE_TYPE 0x0100
65#define DEVICE_TYPE_EP 0x0
66#define DEVICE_TYPE_LEG_EP 0x1
67#define DEVICE_TYPE_RC 0x4
68
60#define PCIECTRL_DRA7XX_CONF_DEVICE_CMD 0x0104 69#define PCIECTRL_DRA7XX_CONF_DEVICE_CMD 0x0104
61#define LTSSM_EN 0x1 70#define LTSSM_EN 0x1
62 71
@@ -66,6 +75,13 @@
66 75
67#define EXP_CAP_ID_OFFSET 0x70 76#define EXP_CAP_ID_OFFSET 0x70
68 77
78#define PCIECTRL_TI_CONF_INTX_ASSERT 0x0124
79#define PCIECTRL_TI_CONF_INTX_DEASSERT 0x0128
80
81#define PCIECTRL_TI_CONF_MSI_XMT 0x012c
82#define MSI_REQ_GRANT BIT(0)
83#define MSI_VECTOR_SHIFT 7
84
69struct dra7xx_pcie { 85struct dra7xx_pcie {
70 struct dw_pcie *pci; 86 struct dw_pcie *pci;
71 void __iomem *base; /* DT ti_conf */ 87 void __iomem *base; /* DT ti_conf */
@@ -73,6 +89,11 @@ struct dra7xx_pcie {
73 struct phy **phy; 89 struct phy **phy;
74 int link_gen; 90 int link_gen;
75 struct irq_domain *irq_domain; 91 struct irq_domain *irq_domain;
92 enum dw_pcie_device_mode mode;
93};
94
95struct dra7xx_pcie_of_data {
96 enum dw_pcie_device_mode mode;
76}; 97};
77 98
78#define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev) 99#define to_dra7xx_pcie(x) dev_get_drvdata((x)->dev)
@@ -88,6 +109,11 @@ static inline void dra7xx_pcie_writel(struct dra7xx_pcie *pcie, u32 offset,
88 writel(value, pcie->base + offset); 109 writel(value, pcie->base + offset);
89} 110}
90 111
112static u64 dra7xx_pcie_cpu_addr_fixup(u64 pci_addr)
113{
114 return pci_addr & DRA7XX_CPU_TO_BUS_ADDR;
115}
116
91static int dra7xx_pcie_link_up(struct dw_pcie *pci) 117static int dra7xx_pcie_link_up(struct dw_pcie *pci)
92{ 118{
93 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); 119 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
@@ -96,9 +122,19 @@ static int dra7xx_pcie_link_up(struct dw_pcie *pci)
96 return !!(reg & LINK_UP); 122 return !!(reg & LINK_UP);
97} 123}
98 124
99static int dra7xx_pcie_establish_link(struct dra7xx_pcie *dra7xx) 125static void dra7xx_pcie_stop_link(struct dw_pcie *pci)
100{ 126{
101 struct dw_pcie *pci = dra7xx->pci; 127 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
128 u32 reg;
129
130 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD);
131 reg &= ~LTSSM_EN;
132 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);
133}
134
135static int dra7xx_pcie_establish_link(struct dw_pcie *pci)
136{
137 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
102 struct device *dev = pci->dev; 138 struct device *dev = pci->dev;
103 u32 reg; 139 u32 reg;
104 u32 exp_cap_off = EXP_CAP_ID_OFFSET; 140 u32 exp_cap_off = EXP_CAP_ID_OFFSET;
@@ -132,34 +168,42 @@ static int dra7xx_pcie_establish_link(struct dra7xx_pcie *dra7xx)
132 reg |= LTSSM_EN; 168 reg |= LTSSM_EN;
133 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg); 169 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_DEVICE_CMD, reg);
134 170
135 return dw_pcie_wait_for_link(pci); 171 return 0;
136} 172}
137 173
138static void dra7xx_pcie_enable_interrupts(struct dra7xx_pcie *dra7xx) 174static void dra7xx_pcie_enable_msi_interrupts(struct dra7xx_pcie *dra7xx)
139{ 175{
140 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN,
141 ~INTERRUPTS);
142 dra7xx_pcie_writel(dra7xx,
143 PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN, INTERRUPTS);
144 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI, 176 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MSI,
145 ~LEG_EP_INTERRUPTS & ~MSI); 177 ~LEG_EP_INTERRUPTS & ~MSI);
146 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI, 178
179 dra7xx_pcie_writel(dra7xx,
180 PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MSI,
147 MSI | LEG_EP_INTERRUPTS); 181 MSI | LEG_EP_INTERRUPTS);
148} 182}
149 183
184static void dra7xx_pcie_enable_wrapper_interrupts(struct dra7xx_pcie *dra7xx)
185{
186 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN,
187 ~INTERRUPTS);
188 dra7xx_pcie_writel(dra7xx, PCIECTRL_DRA7XX_CONF_IRQENABLE_SET_MAIN,
189 INTERRUPTS);
190}
191
192static void dra7xx_pcie_enable_interrupts(struct dra7xx_pcie *dra7xx)
193{
194 dra7xx_pcie_enable_wrapper_interrupts(dra7xx);
195 dra7xx_pcie_enable_msi_interrupts(dra7xx);
196}
197
150static void dra7xx_pcie_host_init(struct pcie_port *pp) 198static void dra7xx_pcie_host_init(struct pcie_port *pp)
151{ 199{
152 struct dw_pcie *pci = to_dw_pcie_from_pp(pp); 200 struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
153 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci); 201 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
154 202
155 pp->io_base &= DRA7XX_CPU_TO_BUS_ADDR;
156 pp->mem_base &= DRA7XX_CPU_TO_BUS_ADDR;
157 pp->cfg0_base &= DRA7XX_CPU_TO_BUS_ADDR;
158 pp->cfg1_base &= DRA7XX_CPU_TO_BUS_ADDR;
159
160 dw_pcie_setup_rc(pp); 203 dw_pcie_setup_rc(pp);
161 204
162 dra7xx_pcie_establish_link(dra7xx); 205 dra7xx_pcie_establish_link(pci);
206 dw_pcie_wait_for_link(pci);
163 dw_pcie_msi_init(pp); 207 dw_pcie_msi_init(pp);
164 dra7xx_pcie_enable_interrupts(dra7xx); 208 dra7xx_pcie_enable_interrupts(dra7xx);
165} 209}
@@ -237,6 +281,7 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
237 struct dra7xx_pcie *dra7xx = arg; 281 struct dra7xx_pcie *dra7xx = arg;
238 struct dw_pcie *pci = dra7xx->pci; 282 struct dw_pcie *pci = dra7xx->pci;
239 struct device *dev = pci->dev; 283 struct device *dev = pci->dev;
284 struct dw_pcie_ep *ep = &pci->ep;
240 u32 reg; 285 u32 reg;
241 286
242 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN); 287 reg = dra7xx_pcie_readl(dra7xx, PCIECTRL_DRA7XX_CONF_IRQSTATUS_MAIN);
@@ -273,8 +318,11 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
273 if (reg & LINK_REQ_RST) 318 if (reg & LINK_REQ_RST)
274 dev_dbg(dev, "Link Request Reset\n"); 319 dev_dbg(dev, "Link Request Reset\n");
275 320
276 if (reg & LINK_UP_EVT) 321 if (reg & LINK_UP_EVT) {
322 if (dra7xx->mode == DW_PCIE_EP_TYPE)
323 dw_pcie_ep_linkup(ep);
277 dev_dbg(dev, "Link-up state change\n"); 324 dev_dbg(dev, "Link-up state change\n");
325 }
278 326
279 if (reg & CFG_BME_EVT) 327 if (reg & CFG_BME_EVT)
280 dev_dbg(dev, "CFG 'Bus Master Enable' change\n"); 328 dev_dbg(dev, "CFG 'Bus Master Enable' change\n");
@@ -287,6 +335,94 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
287 return IRQ_HANDLED; 335 return IRQ_HANDLED;
288} 336}
289 337
338static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep)
339{
340 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
341 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
342
343 dra7xx_pcie_enable_wrapper_interrupts(dra7xx);
344}
345
346static void dra7xx_pcie_raise_legacy_irq(struct dra7xx_pcie *dra7xx)
347{
348 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_INTX_ASSERT, 0x1);
349 mdelay(1);
350 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_INTX_DEASSERT, 0x1);
351}
352
353static void dra7xx_pcie_raise_msi_irq(struct dra7xx_pcie *dra7xx,
354 u8 interrupt_num)
355{
356 u32 reg;
357
358 reg = (interrupt_num - 1) << MSI_VECTOR_SHIFT;
359 reg |= MSI_REQ_GRANT;
360 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_MSI_XMT, reg);
361}
362
363static int dra7xx_pcie_raise_irq(struct dw_pcie_ep *ep,
364 enum pci_epc_irq_type type, u8 interrupt_num)
365{
366 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
367 struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
368
369 switch (type) {
370 case PCI_EPC_IRQ_LEGACY:
371 dra7xx_pcie_raise_legacy_irq(dra7xx);
372 break;
373 case PCI_EPC_IRQ_MSI:
374 dra7xx_pcie_raise_msi_irq(dra7xx, interrupt_num);
375 break;
376 default:
377 dev_err(pci->dev, "UNKNOWN IRQ type\n");
378 }
379
380 return 0;
381}
382
383static struct dw_pcie_ep_ops pcie_ep_ops = {
384 .ep_init = dra7xx_pcie_ep_init,
385 .raise_irq = dra7xx_pcie_raise_irq,
386};
387
388static int __init dra7xx_add_pcie_ep(struct dra7xx_pcie *dra7xx,
389 struct platform_device *pdev)
390{
391 int ret;
392 struct dw_pcie_ep *ep;
393 struct resource *res;
394 struct device *dev = &pdev->dev;
395 struct dw_pcie *pci = dra7xx->pci;
396
397 ep = &pci->ep;
398 ep->ops = &pcie_ep_ops;
399
400 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ep_dbics");
401 pci->dbi_base = devm_ioremap(dev, res->start, resource_size(res));
402 if (!pci->dbi_base)
403 return -ENOMEM;
404
405 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ep_dbics2");
406 pci->dbi_base2 = devm_ioremap(dev, res->start, resource_size(res));
407 if (!pci->dbi_base2)
408 return -ENOMEM;
409
410 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "addr_space");
411 if (!res)
412 return -EINVAL;
413
414 ep->phys_base = res->start;
415 ep->addr_size = resource_size(res);
416
417 ret = dw_pcie_ep_init(ep);
418 if (ret) {
419 dev_err(dev, "failed to initialize endpoint\n");
420 return ret;
421 }
422
423 return 0;
424}
425
290static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx, 426static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
291 struct platform_device *pdev) 427 struct platform_device *pdev)
292{ 428{
@@ -329,6 +465,9 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
329} 465}
330 466
331static const struct dw_pcie_ops dw_pcie_ops = { 467static const struct dw_pcie_ops dw_pcie_ops = {
468 .cpu_addr_fixup = dra7xx_pcie_cpu_addr_fixup,
469 .start_link = dra7xx_pcie_establish_link,
470 .stop_link = dra7xx_pcie_stop_link,
332 .link_up = dra7xx_pcie_link_up, 471 .link_up = dra7xx_pcie_link_up,
333}; 472};
334 473
@@ -371,6 +510,68 @@ err_phy:
371 return ret; 510 return ret;
372} 511}
373 512
513static const struct dra7xx_pcie_of_data dra7xx_pcie_rc_of_data = {
514 .mode = DW_PCIE_RC_TYPE,
515};
516
517static const struct dra7xx_pcie_of_data dra7xx_pcie_ep_of_data = {
518 .mode = DW_PCIE_EP_TYPE,
519};
520
521static const struct of_device_id of_dra7xx_pcie_match[] = {
522 {
523 .compatible = "ti,dra7-pcie",
524 .data = &dra7xx_pcie_rc_of_data,
525 },
526 {
527 .compatible = "ti,dra7-pcie-ep",
528 .data = &dra7xx_pcie_ep_of_data,
529 },
530 {},
531};
532
533/*
534 * dra7xx_pcie_ep_unaligned_memaccess: workaround for AM572x/AM571x Errata i870
535 * @dra7xx: the dra7xx device where the workaround should be applied
536 *
537 * Access to the PCIe slave port that are not 32-bit aligned will result
538 * in incorrect mapping to TLP Address and Byte enable fields. Therefore,
539 * byte and half-word accesses are not possible to byte offset 0x1, 0x2, or
540 * 0x3.
541 *
542 * To avoid this issue set PCIE_SS1_AXI2OCP_LEGACY_MODE_ENABLE to 1.
543 */
544static int dra7xx_pcie_ep_unaligned_memaccess(struct device *dev)
545{
546 int ret;
547 struct device_node *np = dev->of_node;
548 struct of_phandle_args args;
549 struct regmap *regmap;
550
551 regmap = syscon_regmap_lookup_by_phandle(np,
552 "ti,syscon-unaligned-access");
553 if (IS_ERR(regmap)) {
554 dev_dbg(dev, "can't get ti,syscon-unaligned-access\n");
555 return -EINVAL;
556 }
557
558 ret = of_parse_phandle_with_fixed_args(np, "ti,syscon-unaligned-access",
559 2, 0, &args);
560 if (ret) {
561 dev_err(dev, "failed to parse ti,syscon-unaligned-access\n");
562 return ret;
563 }
564
565 ret = regmap_update_bits(regmap, args.args[0], args.args[1],
566 args.args[1]);
567 if (ret)
568 dev_err(dev, "failed to enable unaligned access\n");
569
570 of_node_put(args.np);
571
572 return ret;
573}
574
374static int __init dra7xx_pcie_probe(struct platform_device *pdev) 575static int __init dra7xx_pcie_probe(struct platform_device *pdev)
375{ 576{
376 u32 reg; 577 u32 reg;
@@ -388,6 +589,16 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
388 struct device_node *np = dev->of_node; 589 struct device_node *np = dev->of_node;
389 char name[10]; 590 char name[10];
390 struct gpio_desc *reset; 591 struct gpio_desc *reset;
592 const struct of_device_id *match;
593 const struct dra7xx_pcie_of_data *data;
594 enum dw_pcie_device_mode mode;
595
596 match = of_match_device(of_match_ptr(of_dra7xx_pcie_match), dev);
597 if (!match)
598 return -EINVAL;
599
600 data = (struct dra7xx_pcie_of_data *)match->data;
601 mode = (enum dw_pcie_device_mode)data->mode;
391 602
392 dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL); 603 dra7xx = devm_kzalloc(dev, sizeof(*dra7xx), GFP_KERNEL);
393 if (!dra7xx) 604 if (!dra7xx)
@@ -409,13 +620,6 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
409 return -EINVAL; 620 return -EINVAL;
410 } 621 }
411 622
412 ret = devm_request_irq(dev, irq, dra7xx_pcie_irq_handler,
413 IRQF_SHARED, "dra7xx-pcie-main", dra7xx);
414 if (ret) {
415 dev_err(dev, "failed to request irq\n");
416 return ret;
417 }
418
419 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf"); 623 res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ti_conf");
420 base = devm_ioremap_nocache(dev, res->start, resource_size(res)); 624 base = devm_ioremap_nocache(dev, res->start, resource_size(res));
421 if (!base) 625 if (!base)
@@ -473,9 +677,37 @@ static int __init dra7xx_pcie_probe(struct platform_device *pdev)
473 if (dra7xx->link_gen < 0 || dra7xx->link_gen > 2) 677 if (dra7xx->link_gen < 0 || dra7xx->link_gen > 2)
474 dra7xx->link_gen = 2; 678 dra7xx->link_gen = 2;
475 679
476 ret = dra7xx_add_pcie_port(dra7xx, pdev); 680 switch (mode) {
477 if (ret < 0) 681 case DW_PCIE_RC_TYPE:
682 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
683 DEVICE_TYPE_RC);
684 ret = dra7xx_add_pcie_port(dra7xx, pdev);
685 if (ret < 0)
686 goto err_gpio;
687 break;
688 case DW_PCIE_EP_TYPE:
689 dra7xx_pcie_writel(dra7xx, PCIECTRL_TI_CONF_DEVICE_TYPE,
690 DEVICE_TYPE_EP);
691
692 ret = dra7xx_pcie_ep_unaligned_memaccess(dev);
693 if (ret)
694 goto err_gpio;
695
696 ret = dra7xx_add_pcie_ep(dra7xx, pdev);
697 if (ret < 0)
698 goto err_gpio;
699 break;
700 default:
701 dev_err(dev, "INVALID device type %d\n", mode);
702 }
703 dra7xx->mode = mode;
704
705 ret = devm_request_irq(dev, irq, dra7xx_pcie_irq_handler,
706 IRQF_SHARED, "dra7xx-pcie-main", dra7xx);
707 if (ret) {
708 dev_err(dev, "failed to request irq\n");
478 goto err_gpio; 709 goto err_gpio;
710 }
479 711
480 return 0; 712 return 0;
481 713
@@ -496,6 +728,9 @@ static int dra7xx_pcie_suspend(struct device *dev)
496 struct dw_pcie *pci = dra7xx->pci; 728 struct dw_pcie *pci = dra7xx->pci;
497 u32 val; 729 u32 val;
498 730
731 if (dra7xx->mode != DW_PCIE_RC_TYPE)
732 return 0;
733
499 /* clear MSE */ 734 /* clear MSE */
500 val = dw_pcie_readl_dbi(pci, PCI_COMMAND); 735 val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
501 val &= ~PCI_COMMAND_MEMORY; 736 val &= ~PCI_COMMAND_MEMORY;
@@ -510,6 +745,9 @@ static int dra7xx_pcie_resume(struct device *dev)
510 struct dw_pcie *pci = dra7xx->pci; 745 struct dw_pcie *pci = dra7xx->pci;
511 u32 val; 746 u32 val;
512 747
748 if (dra7xx->mode != DW_PCIE_RC_TYPE)
749 return 0;
750
513 /* set MSE */ 751 /* set MSE */
514 val = dw_pcie_readl_dbi(pci, PCI_COMMAND); 752 val = dw_pcie_readl_dbi(pci, PCI_COMMAND);
515 val |= PCI_COMMAND_MEMORY; 753 val |= PCI_COMMAND_MEMORY;
@@ -548,11 +786,6 @@ static const struct dev_pm_ops dra7xx_pcie_pm_ops = {
548 dra7xx_pcie_resume_noirq) 786 dra7xx_pcie_resume_noirq)
549}; 787};
550 788
551static const struct of_device_id of_dra7xx_pcie_match[] = {
552 { .compatible = "ti,dra7-pcie", },
553 {},
554};
555
556static struct platform_driver dra7xx_pcie_driver = { 789static struct platform_driver dra7xx_pcie_driver = {
557 .driver = { 790 .driver = {
558 .name = "dra7-pcie", 791 .name = "dra7-pcie",
diff --git a/drivers/pci/dwc/pci-exynos.c b/drivers/pci/dwc/pci-exynos.c
index 993b650ef275..546082ad5a3f 100644
--- a/drivers/pci/dwc/pci-exynos.c
+++ b/drivers/pci/dwc/pci-exynos.c
@@ -132,10 +132,6 @@ static int exynos5440_pcie_get_mem_resources(struct platform_device *pdev,
132 struct device *dev = pci->dev; 132 struct device *dev = pci->dev;
133 struct resource *res; 133 struct resource *res;
134 134
135 /* If using the PHY framework, doesn't need to get other resource */
136 if (ep->using_phy)
137 return 0;
138
139 ep->mem_res = devm_kzalloc(dev, sizeof(*ep->mem_res), GFP_KERNEL); 135 ep->mem_res = devm_kzalloc(dev, sizeof(*ep->mem_res), GFP_KERNEL);
140 if (!ep->mem_res) 136 if (!ep->mem_res)
141 return -ENOMEM; 137 return -ENOMEM;
@@ -145,6 +141,10 @@ static int exynos5440_pcie_get_mem_resources(struct platform_device *pdev,
145 if (IS_ERR(ep->mem_res->elbi_base)) 141 if (IS_ERR(ep->mem_res->elbi_base))
146 return PTR_ERR(ep->mem_res->elbi_base); 142 return PTR_ERR(ep->mem_res->elbi_base);
147 143
144 /* If using the PHY framework, doesn't need to get other resource */
145 if (ep->using_phy)
146 return 0;
147
148 res = platform_get_resource(pdev, IORESOURCE_MEM, 1); 148 res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
149 ep->mem_res->phy_base = devm_ioremap_resource(dev, res); 149 ep->mem_res->phy_base = devm_ioremap_resource(dev, res);
150 if (IS_ERR(ep->mem_res->phy_base)) 150 if (IS_ERR(ep->mem_res->phy_base))
@@ -521,23 +521,25 @@ static void exynos_pcie_enable_interrupts(struct exynos_pcie *ep)
521 exynos_pcie_msi_init(ep); 521 exynos_pcie_msi_init(ep);
522} 522}
523 523
524static u32 exynos_pcie_readl_dbi(struct dw_pcie *pci, u32 reg) 524static u32 exynos_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base,
525 u32 reg, size_t size)
525{ 526{
526 struct exynos_pcie *ep = to_exynos_pcie(pci); 527 struct exynos_pcie *ep = to_exynos_pcie(pci);
527 u32 val; 528 u32 val;
528 529
529 exynos_pcie_sideband_dbi_r_mode(ep, true); 530 exynos_pcie_sideband_dbi_r_mode(ep, true);
530 val = readl(pci->dbi_base + reg); 531 dw_pcie_read(base + reg, size, &val);
531 exynos_pcie_sideband_dbi_r_mode(ep, false); 532 exynos_pcie_sideband_dbi_r_mode(ep, false);
532 return val; 533 return val;
533} 534}
534 535
535static void exynos_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val) 536static void exynos_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base,
537 u32 reg, size_t size, u32 val)
536{ 538{
537 struct exynos_pcie *ep = to_exynos_pcie(pci); 539 struct exynos_pcie *ep = to_exynos_pcie(pci);
538 540
539 exynos_pcie_sideband_dbi_w_mode(ep, true); 541 exynos_pcie_sideband_dbi_w_mode(ep, true);
540 writel(val, pci->dbi_base + reg); 542 dw_pcie_write(base + reg, size, val);
541 exynos_pcie_sideband_dbi_w_mode(ep, false); 543 exynos_pcie_sideband_dbi_w_mode(ep, false);
542} 544}
543 545
@@ -644,8 +646,8 @@ static int __init exynos_add_pcie_port(struct exynos_pcie *ep,
644} 646}
645 647
646static const struct dw_pcie_ops dw_pcie_ops = { 648static const struct dw_pcie_ops dw_pcie_ops = {
647 .readl_dbi = exynos_pcie_readl_dbi, 649 .read_dbi = exynos_pcie_read_dbi,
648 .writel_dbi = exynos_pcie_writel_dbi, 650 .write_dbi = exynos_pcie_write_dbi,
649 .link_up = exynos_pcie_link_up, 651 .link_up = exynos_pcie_link_up,
650}; 652};
651 653
diff --git a/drivers/pci/dwc/pcie-artpec6.c b/drivers/pci/dwc/pcie-artpec6.c
index fcd3ef845883..5b3b3afc0edb 100644
--- a/drivers/pci/dwc/pcie-artpec6.c
+++ b/drivers/pci/dwc/pcie-artpec6.c
@@ -78,6 +78,11 @@ static void artpec6_pcie_writel(struct artpec6_pcie *artpec6_pcie, u32 offset, u
78 regmap_write(artpec6_pcie->regmap, offset, val); 78 regmap_write(artpec6_pcie->regmap, offset, val);
79} 79}
80 80
81static u64 artpec6_pcie_cpu_addr_fixup(u64 pci_addr)
82{
83 return pci_addr & ARTPEC6_CPU_TO_BUS_ADDR;
84}
85
81static int artpec6_pcie_establish_link(struct artpec6_pcie *artpec6_pcie) 86static int artpec6_pcie_establish_link(struct artpec6_pcie *artpec6_pcie)
82{ 87{
83 struct dw_pcie *pci = artpec6_pcie->pci; 88 struct dw_pcie *pci = artpec6_pcie->pci;
@@ -142,11 +147,6 @@ static int artpec6_pcie_establish_link(struct artpec6_pcie *artpec6_pcie)
142 */ 147 */
143 dw_pcie_writel_dbi(pci, MISC_CONTROL_1_OFF, DBI_RO_WR_EN); 148 dw_pcie_writel_dbi(pci, MISC_CONTROL_1_OFF, DBI_RO_WR_EN);
144 149
145 pp->io_base &= ARTPEC6_CPU_TO_BUS_ADDR;
146 pp->mem_base &= ARTPEC6_CPU_TO_BUS_ADDR;
147 pp->cfg0_base &= ARTPEC6_CPU_TO_BUS_ADDR;
148 pp->cfg1_base &= ARTPEC6_CPU_TO_BUS_ADDR;
149
150 /* setup root complex */ 150 /* setup root complex */
151 dw_pcie_setup_rc(pp); 151 dw_pcie_setup_rc(pp);
152 152
@@ -234,6 +234,10 @@ static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
234 return 0; 234 return 0;
235} 235}
236 236
237static const struct dw_pcie_ops dw_pcie_ops = {
238 .cpu_addr_fixup = artpec6_pcie_cpu_addr_fixup,
239};
240
237static int artpec6_pcie_probe(struct platform_device *pdev) 241static int artpec6_pcie_probe(struct platform_device *pdev)
238{ 242{
239 struct device *dev = &pdev->dev; 243 struct device *dev = &pdev->dev;
@@ -252,6 +256,7 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
252 return -ENOMEM; 256 return -ENOMEM;
253 257
254 pci->dev = dev; 258 pci->dev = dev;
259 pci->ops = &dw_pcie_ops;
255 260
256 artpec6_pcie->pci = pci; 261 artpec6_pcie->pci = pci;
257 262
diff --git a/drivers/pci/dwc/pcie-designware-ep.c b/drivers/pci/dwc/pcie-designware-ep.c
new file mode 100644
index 000000000000..398406393f37
--- /dev/null
+++ b/drivers/pci/dwc/pcie-designware-ep.c
@@ -0,0 +1,342 @@
1/**
2 * Synopsys Designware PCIe Endpoint controller driver
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/of.h>
21
22#include "pcie-designware.h"
23#include <linux/pci-epc.h>
24#include <linux/pci-epf.h>
25
26void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
27{
28 struct pci_epc *epc = ep->epc;
29
30 pci_epc_linkup(epc);
31}
32
33static void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar)
34{
35 u32 reg;
36
37 reg = PCI_BASE_ADDRESS_0 + (4 * bar);
38 dw_pcie_writel_dbi2(pci, reg, 0x0);
39 dw_pcie_writel_dbi(pci, reg, 0x0);
40}
41
42static int dw_pcie_ep_write_header(struct pci_epc *epc,
43 struct pci_epf_header *hdr)
44{
45 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
46 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
47
48 dw_pcie_writew_dbi(pci, PCI_VENDOR_ID, hdr->vendorid);
49 dw_pcie_writew_dbi(pci, PCI_DEVICE_ID, hdr->deviceid);
50 dw_pcie_writeb_dbi(pci, PCI_REVISION_ID, hdr->revid);
51 dw_pcie_writeb_dbi(pci, PCI_CLASS_PROG, hdr->progif_code);
52 dw_pcie_writew_dbi(pci, PCI_CLASS_DEVICE,
53 hdr->subclass_code | hdr->baseclass_code << 8);
54 dw_pcie_writeb_dbi(pci, PCI_CACHE_LINE_SIZE,
55 hdr->cache_line_size);
56 dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_VENDOR_ID,
57 hdr->subsys_vendor_id);
58 dw_pcie_writew_dbi(pci, PCI_SUBSYSTEM_ID, hdr->subsys_id);
59 dw_pcie_writeb_dbi(pci, PCI_INTERRUPT_PIN,
60 hdr->interrupt_pin);
61
62 return 0;
63}
64
65static int dw_pcie_ep_inbound_atu(struct dw_pcie_ep *ep, enum pci_barno bar,
66 dma_addr_t cpu_addr,
67 enum dw_pcie_as_type as_type)
68{
69 int ret;
70 u32 free_win;
71 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
72
73 free_win = find_first_zero_bit(&ep->ib_window_map,
74 sizeof(ep->ib_window_map));
75 if (free_win >= ep->num_ib_windows) {
76 dev_err(pci->dev, "no free inbound window\n");
77 return -EINVAL;
78 }
79
80 ret = dw_pcie_prog_inbound_atu(pci, free_win, bar, cpu_addr,
81 as_type);
82 if (ret < 0) {
83 dev_err(pci->dev, "Failed to program IB window\n");
84 return ret;
85 }
86
87 ep->bar_to_atu[bar] = free_win;
88 set_bit(free_win, &ep->ib_window_map);
89
90 return 0;
91}
92
93static int dw_pcie_ep_outbound_atu(struct dw_pcie_ep *ep, phys_addr_t phys_addr,
94 u64 pci_addr, size_t size)
95{
96 u32 free_win;
97 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
98
99 free_win = find_first_zero_bit(&ep->ob_window_map,
100 sizeof(ep->ob_window_map));
101 if (free_win >= ep->num_ob_windows) {
102 dev_err(pci->dev, "no free outbound window\n");
103 return -EINVAL;
104 }
105
106 dw_pcie_prog_outbound_atu(pci, free_win, PCIE_ATU_TYPE_MEM,
107 phys_addr, pci_addr, size);
108
109 set_bit(free_win, &ep->ob_window_map);
110 ep->outbound_addr[free_win] = phys_addr;
111
112 return 0;
113}
114
115static void dw_pcie_ep_clear_bar(struct pci_epc *epc, enum pci_barno bar)
116{
117 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
118 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
119 u32 atu_index = ep->bar_to_atu[bar];
120
121 dw_pcie_ep_reset_bar(pci, bar);
122
123 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_INBOUND);
124 clear_bit(atu_index, &ep->ib_window_map);
125}
126
127static int dw_pcie_ep_set_bar(struct pci_epc *epc, enum pci_barno bar,
128 dma_addr_t bar_phys, size_t size, int flags)
129{
130 int ret;
131 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
132 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
133 enum dw_pcie_as_type as_type;
134 u32 reg = PCI_BASE_ADDRESS_0 + (4 * bar);
135
136 if (!(flags & PCI_BASE_ADDRESS_SPACE))
137 as_type = DW_PCIE_AS_MEM;
138 else
139 as_type = DW_PCIE_AS_IO;
140
141 ret = dw_pcie_ep_inbound_atu(ep, bar, bar_phys, as_type);
142 if (ret)
143 return ret;
144
145 dw_pcie_writel_dbi2(pci, reg, size - 1);
146 dw_pcie_writel_dbi(pci, reg, flags);
147
148 return 0;
149}
150
151static int dw_pcie_find_index(struct dw_pcie_ep *ep, phys_addr_t addr,
152 u32 *atu_index)
153{
154 u32 index;
155
156 for (index = 0; index < ep->num_ob_windows; index++) {
157 if (ep->outbound_addr[index] != addr)
158 continue;
159 *atu_index = index;
160 return 0;
161 }
162
163 return -EINVAL;
164}
165
166static void dw_pcie_ep_unmap_addr(struct pci_epc *epc, phys_addr_t addr)
167{
168 int ret;
169 u32 atu_index;
170 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
171 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
172
173 ret = dw_pcie_find_index(ep, addr, &atu_index);
174 if (ret < 0)
175 return;
176
177 dw_pcie_disable_atu(pci, atu_index, DW_PCIE_REGION_OUTBOUND);
178 clear_bit(atu_index, &ep->ob_window_map);
179}
180
181static int dw_pcie_ep_map_addr(struct pci_epc *epc, phys_addr_t addr,
182 u64 pci_addr, size_t size)
183{
184 int ret;
185 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
186 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
187
188 ret = dw_pcie_ep_outbound_atu(ep, addr, pci_addr, size);
189 if (ret) {
190 dev_err(pci->dev, "failed to enable address\n");
191 return ret;
192 }
193
194 return 0;
195}
196
197static int dw_pcie_ep_get_msi(struct pci_epc *epc)
198{
199 int val;
200 u32 lower_addr;
201 u32 upper_addr;
202 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
203 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
204
205 val = dw_pcie_readb_dbi(pci, MSI_MESSAGE_CONTROL);
206 val = (val & MSI_CAP_MME_MASK) >> MSI_CAP_MME_SHIFT;
207
208 lower_addr = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_L32);
209 upper_addr = dw_pcie_readl_dbi(pci, MSI_MESSAGE_ADDR_U32);
210
211 if (!(lower_addr || upper_addr))
212 return -EINVAL;
213
214 return val;
215}
216
217static int dw_pcie_ep_set_msi(struct pci_epc *epc, u8 encode_int)
218{
219 int val;
220 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
221 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
222
223 val = (encode_int << MSI_CAP_MMC_SHIFT);
224 dw_pcie_writew_dbi(pci, MSI_MESSAGE_CONTROL, val);
225
226 return 0;
227}
228
229static int dw_pcie_ep_raise_irq(struct pci_epc *epc,
230 enum pci_epc_irq_type type, u8 interrupt_num)
231{
232 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
233
234 if (!ep->ops->raise_irq)
235 return -EINVAL;
236
237 return ep->ops->raise_irq(ep, type, interrupt_num);
238}
239
240static void dw_pcie_ep_stop(struct pci_epc *epc)
241{
242 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
243 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
244
245 if (!pci->ops->stop_link)
246 return;
247
248 pci->ops->stop_link(pci);
249}
250
251static int dw_pcie_ep_start(struct pci_epc *epc)
252{
253 struct dw_pcie_ep *ep = epc_get_drvdata(epc);
254 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
255
256 if (!pci->ops->start_link)
257 return -EINVAL;
258
259 return pci->ops->start_link(pci);
260}
261
262static const struct pci_epc_ops epc_ops = {
263 .write_header = dw_pcie_ep_write_header,
264 .set_bar = dw_pcie_ep_set_bar,
265 .clear_bar = dw_pcie_ep_clear_bar,
266 .map_addr = dw_pcie_ep_map_addr,
267 .unmap_addr = dw_pcie_ep_unmap_addr,
268 .set_msi = dw_pcie_ep_set_msi,
269 .get_msi = dw_pcie_ep_get_msi,
270 .raise_irq = dw_pcie_ep_raise_irq,
271 .start = dw_pcie_ep_start,
272 .stop = dw_pcie_ep_stop,
273};
274
275void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
276{
277 struct pci_epc *epc = ep->epc;
278
279 pci_epc_mem_exit(epc);
280}
281
282int dw_pcie_ep_init(struct dw_pcie_ep *ep)
283{
284 int ret;
285 void *addr;
286 enum pci_barno bar;
287 struct pci_epc *epc;
288 struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
289 struct device *dev = pci->dev;
290 struct device_node *np = dev->of_node;
291
292 if (!pci->dbi_base || !pci->dbi_base2) {
293 dev_err(dev, "dbi_base/deb_base2 is not populated\n");
294 return -EINVAL;
295 }
296
297 ret = of_property_read_u32(np, "num-ib-windows", &ep->num_ib_windows);
298 if (ret < 0) {
299 dev_err(dev, "unable to read *num-ib-windows* property\n");
300 return ret;
301 }
302
303 ret = of_property_read_u32(np, "num-ob-windows", &ep->num_ob_windows);
304 if (ret < 0) {
305 dev_err(dev, "unable to read *num-ob-windows* property\n");
306 return ret;
307 }
308
309 addr = devm_kzalloc(dev, sizeof(phys_addr_t) * ep->num_ob_windows,
310 GFP_KERNEL);
311 if (!addr)
312 return -ENOMEM;
313 ep->outbound_addr = addr;
314
315 for (bar = BAR_0; bar <= BAR_5; bar++)
316 dw_pcie_ep_reset_bar(pci, bar);
317
318 if (ep->ops->ep_init)
319 ep->ops->ep_init(ep);
320
321 epc = devm_pci_epc_create(dev, &epc_ops);
322 if (IS_ERR(epc)) {
323 dev_err(dev, "failed to create epc device\n");
324 return PTR_ERR(epc);
325 }
326
327 ret = of_property_read_u8(np, "max-functions", &epc->max_functions);
328 if (ret < 0)
329 epc->max_functions = 1;
330
331 ret = pci_epc_mem_init(epc, ep->phys_base, ep->addr_size);
332 if (ret < 0) {
333 dev_err(dev, "Failed to initialize address space\n");
334 return ret;
335 }
336
337 ep->epc = epc;
338 epc_set_drvdata(epc, ep);
339 dw_pcie_setup(pci);
340
341 return 0;
342}
diff --git a/drivers/pci/dwc/pcie-designware-host.c b/drivers/pci/dwc/pcie-designware-host.c
index 5ba334938b52..aece2962defc 100644
--- a/drivers/pci/dwc/pcie-designware-host.c
+++ b/drivers/pci/dwc/pcie-designware-host.c
@@ -56,24 +56,25 @@ static struct irq_chip dw_msi_irq_chip = {
56/* MSI int handler */ 56/* MSI int handler */
57irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) 57irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
58{ 58{
59 unsigned long val; 59 u32 val;
60 int i, pos, irq; 60 int i, pos, irq;
61 irqreturn_t ret = IRQ_NONE; 61 irqreturn_t ret = IRQ_NONE;
62 62
63 for (i = 0; i < MAX_MSI_CTRLS; i++) { 63 for (i = 0; i < MAX_MSI_CTRLS; i++) {
64 dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4, 64 dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4,
65 (u32 *)&val); 65 &val);
66 if (val) { 66 if (!val)
67 ret = IRQ_HANDLED; 67 continue;
68 pos = 0; 68
69 while ((pos = find_next_bit(&val, 32, pos)) != 32) { 69 ret = IRQ_HANDLED;
70 irq = irq_find_mapping(pp->irq_domain, 70 pos = 0;
71 i * 32 + pos); 71 while ((pos = find_next_bit((unsigned long *) &val, 32,
72 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + 72 pos)) != 32) {
73 i * 12, 4, 1 << pos); 73 irq = irq_find_mapping(pp->irq_domain, i * 32 + pos);
74 generic_handle_irq(irq); 74 dw_pcie_wr_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12,
75 pos++; 75 4, 1 << pos);
76 } 76 generic_handle_irq(irq);
77 pos++;
77 } 78 }
78 } 79 }
79 80
diff --git a/drivers/pci/dwc/pcie-designware-plat.c b/drivers/pci/dwc/pcie-designware-plat.c
index b6c832ba39dd..f20d494922ab 100644
--- a/drivers/pci/dwc/pcie-designware-plat.c
+++ b/drivers/pci/dwc/pcie-designware-plat.c
@@ -86,6 +86,9 @@ static int dw_plat_add_pcie_port(struct pcie_port *pp,
86 return 0; 86 return 0;
87} 87}
88 88
89static const struct dw_pcie_ops dw_pcie_ops = {
90};
91
89static int dw_plat_pcie_probe(struct platform_device *pdev) 92static int dw_plat_pcie_probe(struct platform_device *pdev)
90{ 93{
91 struct device *dev = &pdev->dev; 94 struct device *dev = &pdev->dev;
@@ -103,6 +106,7 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
103 return -ENOMEM; 106 return -ENOMEM;
104 107
105 pci->dev = dev; 108 pci->dev = dev;
109 pci->ops = &dw_pcie_ops;
106 110
107 dw_plat_pcie->pci = pci; 111 dw_plat_pcie->pci = pci;
108 112
diff --git a/drivers/pci/dwc/pcie-designware.c b/drivers/pci/dwc/pcie-designware.c
index 7e1fb7d6643c..0e03af279259 100644
--- a/drivers/pci/dwc/pcie-designware.c
+++ b/drivers/pci/dwc/pcie-designware.c
@@ -61,91 +61,253 @@ int dw_pcie_write(void __iomem *addr, int size, u32 val)
61 return PCIBIOS_SUCCESSFUL; 61 return PCIBIOS_SUCCESSFUL;
62} 62}
63 63
64u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg) 64u32 __dw_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
65 size_t size)
65{ 66{
66 if (pci->ops->readl_dbi) 67 int ret;
67 return pci->ops->readl_dbi(pci, reg); 68 u32 val;
68 69
69 return readl(pci->dbi_base + reg); 70 if (pci->ops->read_dbi)
71 return pci->ops->read_dbi(pci, base, reg, size);
72
73 ret = dw_pcie_read(base + reg, size, &val);
74 if (ret)
75 dev_err(pci->dev, "read DBI address failed\n");
76
77 return val;
70} 78}
71 79
72void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val) 80void __dw_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
81 size_t size, u32 val)
73{ 82{
74 if (pci->ops->writel_dbi) 83 int ret;
75 pci->ops->writel_dbi(pci, reg, val); 84
76 else 85 if (pci->ops->write_dbi) {
77 writel(val, pci->dbi_base + reg); 86 pci->ops->write_dbi(pci, base, reg, size, val);
87 return;
88 }
89
90 ret = dw_pcie_write(base + reg, size, val);
91 if (ret)
92 dev_err(pci->dev, "write DBI address failed\n");
78} 93}
79 94
80static u32 dw_pcie_readl_unroll(struct dw_pcie *pci, u32 index, u32 reg) 95static u32 dw_pcie_readl_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg)
81{ 96{
82 u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); 97 u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
83 98
84 return dw_pcie_readl_dbi(pci, offset + reg); 99 return dw_pcie_readl_dbi(pci, offset + reg);
85} 100}
86 101
87static void dw_pcie_writel_unroll(struct dw_pcie *pci, u32 index, u32 reg, 102static void dw_pcie_writel_ob_unroll(struct dw_pcie *pci, u32 index, u32 reg,
88 u32 val) 103 u32 val)
89{ 104{
90 u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index); 105 u32 offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
91 106
92 dw_pcie_writel_dbi(pci, offset + reg, val); 107 dw_pcie_writel_dbi(pci, offset + reg, val);
93} 108}
94 109
110void dw_pcie_prog_outbound_atu_unroll(struct dw_pcie *pci, int index, int type,
111 u64 cpu_addr, u64 pci_addr, u32 size)
112{
113 u32 retries, val;
114
115 dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_BASE,
116 lower_32_bits(cpu_addr));
117 dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_BASE,
118 upper_32_bits(cpu_addr));
119 dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LIMIT,
120 lower_32_bits(cpu_addr + size - 1));
121 dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET,
122 lower_32_bits(pci_addr));
123 dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
124 upper_32_bits(pci_addr));
125 dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1,
126 type);
127 dw_pcie_writel_ob_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
128 PCIE_ATU_ENABLE);
129
130 /*
131 * Make sure ATU enable takes effect before any subsequent config
132 * and I/O accesses.
133 */
134 for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
135 val = dw_pcie_readl_ob_unroll(pci, index,
136 PCIE_ATU_UNR_REGION_CTRL2);
137 if (val & PCIE_ATU_ENABLE)
138 return;
139
140 usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
141 }
142 dev_err(pci->dev, "outbound iATU is not being enabled\n");
143}
144
95void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type, 145void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type,
96 u64 cpu_addr, u64 pci_addr, u32 size) 146 u64 cpu_addr, u64 pci_addr, u32 size)
97{ 147{
98 u32 retries, val; 148 u32 retries, val;
99 149
150 if (pci->ops->cpu_addr_fixup)
151 cpu_addr = pci->ops->cpu_addr_fixup(cpu_addr);
152
100 if (pci->iatu_unroll_enabled) { 153 if (pci->iatu_unroll_enabled) {
101 dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_LOWER_BASE, 154 dw_pcie_prog_outbound_atu_unroll(pci, index, type, cpu_addr,
102 lower_32_bits(cpu_addr)); 155 pci_addr, size);
103 dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_UPPER_BASE, 156 return;
104 upper_32_bits(cpu_addr));
105 dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_LIMIT,
106 lower_32_bits(cpu_addr + size - 1));
107 dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET,
108 lower_32_bits(pci_addr));
109 dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
110 upper_32_bits(pci_addr));
111 dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1,
112 type);
113 dw_pcie_writel_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
114 PCIE_ATU_ENABLE);
115 } else {
116 dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT,
117 PCIE_ATU_REGION_OUTBOUND | index);
118 dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE,
119 lower_32_bits(cpu_addr));
120 dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_BASE,
121 upper_32_bits(cpu_addr));
122 dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT,
123 lower_32_bits(cpu_addr + size - 1));
124 dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET,
125 lower_32_bits(pci_addr));
126 dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
127 upper_32_bits(pci_addr));
128 dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type);
129 dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE);
130 } 157 }
131 158
159 dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT,
160 PCIE_ATU_REGION_OUTBOUND | index);
161 dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_BASE,
162 lower_32_bits(cpu_addr));
163 dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_BASE,
164 upper_32_bits(cpu_addr));
165 dw_pcie_writel_dbi(pci, PCIE_ATU_LIMIT,
166 lower_32_bits(cpu_addr + size - 1));
167 dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET,
168 lower_32_bits(pci_addr));
169 dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET,
170 upper_32_bits(pci_addr));
171 dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type);
172 dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE);
173
132 /* 174 /*
133 * Make sure ATU enable takes effect before any subsequent config 175 * Make sure ATU enable takes effect before any subsequent config
134 * and I/O accesses. 176 * and I/O accesses.
135 */ 177 */
136 for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) { 178 for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
137 if (pci->iatu_unroll_enabled) 179 val = dw_pcie_readl_dbi(pci, PCIE_ATU_CR2);
138 val = dw_pcie_readl_unroll(pci, index,
139 PCIE_ATU_UNR_REGION_CTRL2);
140 else
141 val = dw_pcie_readl_dbi(pci, PCIE_ATU_CR2);
142
143 if (val == PCIE_ATU_ENABLE) 180 if (val == PCIE_ATU_ENABLE)
144 return; 181 return;
145 182
146 usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX); 183 usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
147 } 184 }
148 dev_err(pci->dev, "iATU is not being enabled\n"); 185 dev_err(pci->dev, "outbound iATU is not being enabled\n");
186}
187
188static u32 dw_pcie_readl_ib_unroll(struct dw_pcie *pci, u32 index, u32 reg)
189{
190 u32 offset = PCIE_GET_ATU_INB_UNR_REG_OFFSET(index);
191
192 return dw_pcie_readl_dbi(pci, offset + reg);
193}
194
195static void dw_pcie_writel_ib_unroll(struct dw_pcie *pci, u32 index, u32 reg,
196 u32 val)
197{
198 u32 offset = PCIE_GET_ATU_INB_UNR_REG_OFFSET(index);
199
200 dw_pcie_writel_dbi(pci, offset + reg, val);
201}
202
203int dw_pcie_prog_inbound_atu_unroll(struct dw_pcie *pci, int index, int bar,
204 u64 cpu_addr, enum dw_pcie_as_type as_type)
205{
206 int type;
207 u32 retries, val;
208
209 dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_LOWER_TARGET,
210 lower_32_bits(cpu_addr));
211 dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_UPPER_TARGET,
212 upper_32_bits(cpu_addr));
213
214 switch (as_type) {
215 case DW_PCIE_AS_MEM:
216 type = PCIE_ATU_TYPE_MEM;
217 break;
218 case DW_PCIE_AS_IO:
219 type = PCIE_ATU_TYPE_IO;
220 break;
221 default:
222 return -EINVAL;
223 }
224
225 dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL1, type);
226 dw_pcie_writel_ib_unroll(pci, index, PCIE_ATU_UNR_REGION_CTRL2,
227 PCIE_ATU_ENABLE |
228 PCIE_ATU_BAR_MODE_ENABLE | (bar << 8));
229
230 /*
231 * Make sure ATU enable takes effect before any subsequent config
232 * and I/O accesses.
233 */
234 for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
235 val = dw_pcie_readl_ib_unroll(pci, index,
236 PCIE_ATU_UNR_REGION_CTRL2);
237 if (val & PCIE_ATU_ENABLE)
238 return 0;
239
240 usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
241 }
242 dev_err(pci->dev, "inbound iATU is not being enabled\n");
243
244 return -EBUSY;
245}
246
247int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar,
248 u64 cpu_addr, enum dw_pcie_as_type as_type)
249{
250 int type;
251 u32 retries, val;
252
253 if (pci->iatu_unroll_enabled)
254 return dw_pcie_prog_inbound_atu_unroll(pci, index, bar,
255 cpu_addr, as_type);
256
257 dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, PCIE_ATU_REGION_INBOUND |
258 index);
259 dw_pcie_writel_dbi(pci, PCIE_ATU_LOWER_TARGET, lower_32_bits(cpu_addr));
260 dw_pcie_writel_dbi(pci, PCIE_ATU_UPPER_TARGET, upper_32_bits(cpu_addr));
261
262 switch (as_type) {
263 case DW_PCIE_AS_MEM:
264 type = PCIE_ATU_TYPE_MEM;
265 break;
266 case DW_PCIE_AS_IO:
267 type = PCIE_ATU_TYPE_IO;
268 break;
269 default:
270 return -EINVAL;
271 }
272
273 dw_pcie_writel_dbi(pci, PCIE_ATU_CR1, type);
274 dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, PCIE_ATU_ENABLE
275 | PCIE_ATU_BAR_MODE_ENABLE | (bar << 8));
276
277 /*
278 * Make sure ATU enable takes effect before any subsequent config
279 * and I/O accesses.
280 */
281 for (retries = 0; retries < LINK_WAIT_MAX_IATU_RETRIES; retries++) {
282 val = dw_pcie_readl_dbi(pci, PCIE_ATU_CR2);
283 if (val & PCIE_ATU_ENABLE)
284 return 0;
285
286 usleep_range(LINK_WAIT_IATU_MIN, LINK_WAIT_IATU_MAX);
287 }
288 dev_err(pci->dev, "inbound iATU is not being enabled\n");
289
290 return -EBUSY;
291}
292
293void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
294 enum dw_pcie_region_type type)
295{
296 int region;
297
298 switch (type) {
299 case DW_PCIE_REGION_INBOUND:
300 region = PCIE_ATU_REGION_INBOUND;
301 break;
302 case DW_PCIE_REGION_OUTBOUND:
303 region = PCIE_ATU_REGION_OUTBOUND;
304 break;
305 default:
306 return;
307 }
308
309 dw_pcie_writel_dbi(pci, PCIE_ATU_VIEWPORT, region | index);
310 dw_pcie_writel_dbi(pci, PCIE_ATU_CR2, ~PCIE_ATU_ENABLE);
149} 311}
150 312
151int dw_pcie_wait_for_link(struct dw_pcie *pci) 313int dw_pcie_wait_for_link(struct dw_pcie *pci)
diff --git a/drivers/pci/dwc/pcie-designware.h b/drivers/pci/dwc/pcie-designware.h
index cd3b8713fe50..c6a840575796 100644
--- a/drivers/pci/dwc/pcie-designware.h
+++ b/drivers/pci/dwc/pcie-designware.h
@@ -18,6 +18,9 @@
18#include <linux/msi.h> 18#include <linux/msi.h>
19#include <linux/pci.h> 19#include <linux/pci.h>
20 20
21#include <linux/pci-epc.h>
22#include <linux/pci-epf.h>
23
21/* Parameters for the waiting for link up routine */ 24/* Parameters for the waiting for link up routine */
22#define LINK_WAIT_MAX_RETRIES 10 25#define LINK_WAIT_MAX_RETRIES 10
23#define LINK_WAIT_USLEEP_MIN 90000 26#define LINK_WAIT_USLEEP_MIN 90000
@@ -89,6 +92,16 @@
89#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) \ 92#define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) \
90 ((0x3 << 20) | ((region) << 9)) 93 ((0x3 << 20) | ((region) << 9))
91 94
95#define PCIE_GET_ATU_INB_UNR_REG_OFFSET(region) \
96 ((0x3 << 20) | ((region) << 9) | (0x1 << 8))
97
98#define MSI_MESSAGE_CONTROL 0x52
99#define MSI_CAP_MMC_SHIFT 1
100#define MSI_CAP_MME_SHIFT 4
101#define MSI_CAP_MME_MASK (7 << MSI_CAP_MME_SHIFT)
102#define MSI_MESSAGE_ADDR_L32 0x54
103#define MSI_MESSAGE_ADDR_U32 0x58
104
92/* 105/*
93 * Maximum number of MSI IRQs can be 256 per controller. But keep 106 * Maximum number of MSI IRQs can be 256 per controller. But keep
94 * it 32 as of now. Probably we will never need more than 32. If needed, 107 * it 32 as of now. Probably we will never need more than 32. If needed,
@@ -99,6 +112,20 @@
99 112
100struct pcie_port; 113struct pcie_port;
101struct dw_pcie; 114struct dw_pcie;
115struct dw_pcie_ep;
116
117enum dw_pcie_region_type {
118 DW_PCIE_REGION_UNKNOWN,
119 DW_PCIE_REGION_INBOUND,
120 DW_PCIE_REGION_OUTBOUND,
121};
122
123enum dw_pcie_device_mode {
124 DW_PCIE_UNKNOWN_TYPE,
125 DW_PCIE_EP_TYPE,
126 DW_PCIE_LEG_EP_TYPE,
127 DW_PCIE_RC_TYPE,
128};
102 129
103struct dw_pcie_host_ops { 130struct dw_pcie_host_ops {
104 int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val); 131 int (*rd_own_conf)(struct pcie_port *pp, int where, int size, u32 *val);
@@ -142,35 +169,116 @@ struct pcie_port {
142 DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); 169 DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
143}; 170};
144 171
172enum dw_pcie_as_type {
173 DW_PCIE_AS_UNKNOWN,
174 DW_PCIE_AS_MEM,
175 DW_PCIE_AS_IO,
176};
177
178struct dw_pcie_ep_ops {
179 void (*ep_init)(struct dw_pcie_ep *ep);
180 int (*raise_irq)(struct dw_pcie_ep *ep, enum pci_epc_irq_type type,
181 u8 interrupt_num);
182};
183
184struct dw_pcie_ep {
185 struct pci_epc *epc;
186 struct dw_pcie_ep_ops *ops;
187 phys_addr_t phys_base;
188 size_t addr_size;
189 u8 bar_to_atu[6];
190 phys_addr_t *outbound_addr;
191 unsigned long ib_window_map;
192 unsigned long ob_window_map;
193 u32 num_ib_windows;
194 u32 num_ob_windows;
195};
196
145struct dw_pcie_ops { 197struct dw_pcie_ops {
146 u32 (*readl_dbi)(struct dw_pcie *pcie, u32 reg); 198 u64 (*cpu_addr_fixup)(u64 cpu_addr);
147 void (*writel_dbi)(struct dw_pcie *pcie, u32 reg, u32 val); 199 u32 (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
200 size_t size);
201 void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg,
202 size_t size, u32 val);
148 int (*link_up)(struct dw_pcie *pcie); 203 int (*link_up)(struct dw_pcie *pcie);
204 int (*start_link)(struct dw_pcie *pcie);
205 void (*stop_link)(struct dw_pcie *pcie);
149}; 206};
150 207
151struct dw_pcie { 208struct dw_pcie {
152 struct device *dev; 209 struct device *dev;
153 void __iomem *dbi_base; 210 void __iomem *dbi_base;
211 void __iomem *dbi_base2;
154 u32 num_viewport; 212 u32 num_viewport;
155 u8 iatu_unroll_enabled; 213 u8 iatu_unroll_enabled;
156 struct pcie_port pp; 214 struct pcie_port pp;
215 struct dw_pcie_ep ep;
157 const struct dw_pcie_ops *ops; 216 const struct dw_pcie_ops *ops;
158}; 217};
159 218
160#define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp) 219#define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp)
161 220
221#define to_dw_pcie_from_ep(endpoint) \
222 container_of((endpoint), struct dw_pcie, ep)
223
162int dw_pcie_read(void __iomem *addr, int size, u32 *val); 224int dw_pcie_read(void __iomem *addr, int size, u32 *val);
163int dw_pcie_write(void __iomem *addr, int size, u32 val); 225int dw_pcie_write(void __iomem *addr, int size, u32 val);
164 226
165u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg); 227u32 __dw_pcie_read_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
166void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val); 228 size_t size);
229void __dw_pcie_write_dbi(struct dw_pcie *pci, void __iomem *base, u32 reg,
230 size_t size, u32 val);
167int dw_pcie_link_up(struct dw_pcie *pci); 231int dw_pcie_link_up(struct dw_pcie *pci);
168int dw_pcie_wait_for_link(struct dw_pcie *pci); 232int dw_pcie_wait_for_link(struct dw_pcie *pci);
169void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, 233void dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index,
170 int type, u64 cpu_addr, u64 pci_addr, 234 int type, u64 cpu_addr, u64 pci_addr,
171 u32 size); 235 u32 size);
236int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int bar,
237 u64 cpu_addr, enum dw_pcie_as_type as_type);
238void dw_pcie_disable_atu(struct dw_pcie *pci, int index,
239 enum dw_pcie_region_type type);
172void dw_pcie_setup(struct dw_pcie *pci); 240void dw_pcie_setup(struct dw_pcie *pci);
173 241
242static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val)
243{
244 __dw_pcie_write_dbi(pci, pci->dbi_base, reg, 0x4, val);
245}
246
247static inline u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg)
248{
249 return __dw_pcie_read_dbi(pci, pci->dbi_base, reg, 0x4);
250}
251
252static inline void dw_pcie_writew_dbi(struct dw_pcie *pci, u32 reg, u16 val)
253{
254 __dw_pcie_write_dbi(pci, pci->dbi_base, reg, 0x2, val);
255}
256
257static inline u16 dw_pcie_readw_dbi(struct dw_pcie *pci, u32 reg)
258{
259 return __dw_pcie_read_dbi(pci, pci->dbi_base, reg, 0x2);
260}
261
262static inline void dw_pcie_writeb_dbi(struct dw_pcie *pci, u32 reg, u8 val)
263{
264 __dw_pcie_write_dbi(pci, pci->dbi_base, reg, 0x1, val);
265}
266
267static inline u8 dw_pcie_readb_dbi(struct dw_pcie *pci, u32 reg)
268{
269 return __dw_pcie_read_dbi(pci, pci->dbi_base, reg, 0x1);
270}
271
272static inline void dw_pcie_writel_dbi2(struct dw_pcie *pci, u32 reg, u32 val)
273{
274 __dw_pcie_write_dbi(pci, pci->dbi_base2, reg, 0x4, val);
275}
276
277static inline u32 dw_pcie_readl_dbi2(struct dw_pcie *pci, u32 reg)
278{
279 return __dw_pcie_read_dbi(pci, pci->dbi_base2, reg, 0x4);
280}
281
174#ifdef CONFIG_PCIE_DW_HOST 282#ifdef CONFIG_PCIE_DW_HOST
175irqreturn_t dw_handle_msi_irq(struct pcie_port *pp); 283irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
176void dw_pcie_msi_init(struct pcie_port *pp); 284void dw_pcie_msi_init(struct pcie_port *pp);
@@ -195,4 +303,23 @@ static inline int dw_pcie_host_init(struct pcie_port *pp)
195 return 0; 303 return 0;
196} 304}
197#endif 305#endif
306
307#ifdef CONFIG_PCIE_DW_EP
308void dw_pcie_ep_linkup(struct dw_pcie_ep *ep);
309int dw_pcie_ep_init(struct dw_pcie_ep *ep);
310void dw_pcie_ep_exit(struct dw_pcie_ep *ep);
311#else
312static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep)
313{
314}
315
316static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep)
317{
318 return 0;
319}
320
321static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
322{
323}
324#endif
198#endif /* _PCIE_DESIGNWARE_H */ 325#endif /* _PCIE_DESIGNWARE_H */
diff --git a/drivers/pci/endpoint/Kconfig b/drivers/pci/endpoint/Kconfig
new file mode 100644
index 000000000000..c23f146fb5a6
--- /dev/null
+++ b/drivers/pci/endpoint/Kconfig
@@ -0,0 +1,31 @@
1#
2# PCI Endpoint Support
3#
4
5menu "PCI Endpoint"
6
7config PCI_ENDPOINT
8 bool "PCI Endpoint Support"
9 help
10 Enable this configuration option to support configurable PCI
11 endpoint. This should be enabled if the platform has a PCI
12 controller that can operate in endpoint mode.
13
14 Enabling this option will build the endpoint library, which
15 includes endpoint controller library and endpoint function
16 library.
17
18 If in doubt, say "N" to disable Endpoint support.
19
20config PCI_ENDPOINT_CONFIGFS
21 bool "PCI Endpoint Configfs Support"
22 depends on PCI_ENDPOINT
23 select CONFIGFS_FS
24 help
25 This will enable the configfs entry that can be used to
26 configure the endpoint function and used to bind the
27 function with a endpoint controller.
28
29source "drivers/pci/endpoint/functions/Kconfig"
30
31endmenu
diff --git a/drivers/pci/endpoint/Makefile b/drivers/pci/endpoint/Makefile
new file mode 100644
index 000000000000..1041f80a4645
--- /dev/null
+++ b/drivers/pci/endpoint/Makefile
@@ -0,0 +1,7 @@
1#
2# Makefile for PCI Endpoint Support
3#
4
5obj-$(CONFIG_PCI_ENDPOINT_CONFIGFS) += pci-ep-cfs.o
6obj-$(CONFIG_PCI_ENDPOINT) += pci-epc-core.o pci-epf-core.o\
7 pci-epc-mem.o functions/
diff --git a/drivers/pci/endpoint/functions/Kconfig b/drivers/pci/endpoint/functions/Kconfig
new file mode 100644
index 000000000000..175edad42d2f
--- /dev/null
+++ b/drivers/pci/endpoint/functions/Kconfig
@@ -0,0 +1,12 @@
1#
2# PCI Endpoint Functions
3#
4
5config PCI_EPF_TEST
6 tristate "PCI Endpoint Test driver"
7 depends on PCI_ENDPOINT
8 help
9 Enable this configuration option to enable the test driver
10 for PCI Endpoint.
11
12 If in doubt, say "N" to disable Endpoint test driver.
diff --git a/drivers/pci/endpoint/functions/Makefile b/drivers/pci/endpoint/functions/Makefile
new file mode 100644
index 000000000000..6d94a4801838
--- /dev/null
+++ b/drivers/pci/endpoint/functions/Makefile
@@ -0,0 +1,5 @@
1#
2# Makefile for PCI Endpoint Functions
3#
4
5obj-$(CONFIG_PCI_EPF_TEST) += pci-epf-test.o
diff --git a/drivers/pci/endpoint/functions/pci-epf-test.c b/drivers/pci/endpoint/functions/pci-epf-test.c
new file mode 100644
index 000000000000..53fff8030337
--- /dev/null
+++ b/drivers/pci/endpoint/functions/pci-epf-test.c
@@ -0,0 +1,510 @@
1/**
2 * Test driver to test endpoint functionality
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/crc32.h>
21#include <linux/delay.h>
22#include <linux/io.h>
23#include <linux/module.h>
24#include <linux/slab.h>
25#include <linux/pci_ids.h>
26#include <linux/random.h>
27
28#include <linux/pci-epc.h>
29#include <linux/pci-epf.h>
30#include <linux/pci_regs.h>
31
32#define COMMAND_RAISE_LEGACY_IRQ BIT(0)
33#define COMMAND_RAISE_MSI_IRQ BIT(1)
34#define MSI_NUMBER_SHIFT 2
35#define MSI_NUMBER_MASK (0x3f << MSI_NUMBER_SHIFT)
36#define COMMAND_READ BIT(8)
37#define COMMAND_WRITE BIT(9)
38#define COMMAND_COPY BIT(10)
39
40#define STATUS_READ_SUCCESS BIT(0)
41#define STATUS_READ_FAIL BIT(1)
42#define STATUS_WRITE_SUCCESS BIT(2)
43#define STATUS_WRITE_FAIL BIT(3)
44#define STATUS_COPY_SUCCESS BIT(4)
45#define STATUS_COPY_FAIL BIT(5)
46#define STATUS_IRQ_RAISED BIT(6)
47#define STATUS_SRC_ADDR_INVALID BIT(7)
48#define STATUS_DST_ADDR_INVALID BIT(8)
49
50#define TIMER_RESOLUTION 1
51
52static struct workqueue_struct *kpcitest_workqueue;
53
54struct pci_epf_test {
55 void *reg[6];
56 struct pci_epf *epf;
57 struct delayed_work cmd_handler;
58};
59
60struct pci_epf_test_reg {
61 u32 magic;
62 u32 command;
63 u32 status;
64 u64 src_addr;
65 u64 dst_addr;
66 u32 size;
67 u32 checksum;
68} __packed;
69
70static struct pci_epf_header test_header = {
71 .vendorid = PCI_ANY_ID,
72 .deviceid = PCI_ANY_ID,
73 .baseclass_code = PCI_CLASS_OTHERS,
74 .interrupt_pin = PCI_INTERRUPT_INTA,
75};
76
77static int bar_size[] = { 512, 1024, 16384, 131072, 1048576 };
78
79static int pci_epf_test_copy(struct pci_epf_test *epf_test)
80{
81 int ret;
82 void __iomem *src_addr;
83 void __iomem *dst_addr;
84 phys_addr_t src_phys_addr;
85 phys_addr_t dst_phys_addr;
86 struct pci_epf *epf = epf_test->epf;
87 struct device *dev = &epf->dev;
88 struct pci_epc *epc = epf->epc;
89 struct pci_epf_test_reg *reg = epf_test->reg[0];
90
91 src_addr = pci_epc_mem_alloc_addr(epc, &src_phys_addr, reg->size);
92 if (!src_addr) {
93 dev_err(dev, "failed to allocate source address\n");
94 reg->status = STATUS_SRC_ADDR_INVALID;
95 ret = -ENOMEM;
96 goto err;
97 }
98
99 ret = pci_epc_map_addr(epc, src_phys_addr, reg->src_addr, reg->size);
100 if (ret) {
101 dev_err(dev, "failed to map source address\n");
102 reg->status = STATUS_SRC_ADDR_INVALID;
103 goto err_src_addr;
104 }
105
106 dst_addr = pci_epc_mem_alloc_addr(epc, &dst_phys_addr, reg->size);
107 if (!dst_addr) {
108 dev_err(dev, "failed to allocate destination address\n");
109 reg->status = STATUS_DST_ADDR_INVALID;
110 ret = -ENOMEM;
111 goto err_src_map_addr;
112 }
113
114 ret = pci_epc_map_addr(epc, dst_phys_addr, reg->dst_addr, reg->size);
115 if (ret) {
116 dev_err(dev, "failed to map destination address\n");
117 reg->status = STATUS_DST_ADDR_INVALID;
118 goto err_dst_addr;
119 }
120
121 memcpy(dst_addr, src_addr, reg->size);
122
123 pci_epc_unmap_addr(epc, dst_phys_addr);
124
125err_dst_addr:
126 pci_epc_mem_free_addr(epc, dst_phys_addr, dst_addr, reg->size);
127
128err_src_map_addr:
129 pci_epc_unmap_addr(epc, src_phys_addr);
130
131err_src_addr:
132 pci_epc_mem_free_addr(epc, src_phys_addr, src_addr, reg->size);
133
134err:
135 return ret;
136}
137
138static int pci_epf_test_read(struct pci_epf_test *epf_test)
139{
140 int ret;
141 void __iomem *src_addr;
142 void *buf;
143 u32 crc32;
144 phys_addr_t phys_addr;
145 struct pci_epf *epf = epf_test->epf;
146 struct device *dev = &epf->dev;
147 struct pci_epc *epc = epf->epc;
148 struct pci_epf_test_reg *reg = epf_test->reg[0];
149
150 src_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size);
151 if (!src_addr) {
152 dev_err(dev, "failed to allocate address\n");
153 reg->status = STATUS_SRC_ADDR_INVALID;
154 ret = -ENOMEM;
155 goto err;
156 }
157
158 ret = pci_epc_map_addr(epc, phys_addr, reg->src_addr, reg->size);
159 if (ret) {
160 dev_err(dev, "failed to map address\n");
161 reg->status = STATUS_SRC_ADDR_INVALID;
162 goto err_addr;
163 }
164
165 buf = kzalloc(reg->size, GFP_KERNEL);
166 if (!buf) {
167 ret = -ENOMEM;
168 goto err_map_addr;
169 }
170
171 memcpy(buf, src_addr, reg->size);
172
173 crc32 = crc32_le(~0, buf, reg->size);
174 if (crc32 != reg->checksum)
175 ret = -EIO;
176
177 kfree(buf);
178
179err_map_addr:
180 pci_epc_unmap_addr(epc, phys_addr);
181
182err_addr:
183 pci_epc_mem_free_addr(epc, phys_addr, src_addr, reg->size);
184
185err:
186 return ret;
187}
188
189static int pci_epf_test_write(struct pci_epf_test *epf_test)
190{
191 int ret;
192 void __iomem *dst_addr;
193 void *buf;
194 phys_addr_t phys_addr;
195 struct pci_epf *epf = epf_test->epf;
196 struct device *dev = &epf->dev;
197 struct pci_epc *epc = epf->epc;
198 struct pci_epf_test_reg *reg = epf_test->reg[0];
199
200 dst_addr = pci_epc_mem_alloc_addr(epc, &phys_addr, reg->size);
201 if (!dst_addr) {
202 dev_err(dev, "failed to allocate address\n");
203 reg->status = STATUS_DST_ADDR_INVALID;
204 ret = -ENOMEM;
205 goto err;
206 }
207
208 ret = pci_epc_map_addr(epc, phys_addr, reg->dst_addr, reg->size);
209 if (ret) {
210 dev_err(dev, "failed to map address\n");
211 reg->status = STATUS_DST_ADDR_INVALID;
212 goto err_addr;
213 }
214
215 buf = kzalloc(reg->size, GFP_KERNEL);
216 if (!buf) {
217 ret = -ENOMEM;
218 goto err_map_addr;
219 }
220
221 get_random_bytes(buf, reg->size);
222 reg->checksum = crc32_le(~0, buf, reg->size);
223
224 memcpy(dst_addr, buf, reg->size);
225
226 /*
227 * wait 1ms inorder for the write to complete. Without this delay L3
228 * error in observed in the host system.
229 */
230 mdelay(1);
231
232 kfree(buf);
233
234err_map_addr:
235 pci_epc_unmap_addr(epc, phys_addr);
236
237err_addr:
238 pci_epc_mem_free_addr(epc, phys_addr, dst_addr, reg->size);
239
240err:
241 return ret;
242}
243
244static void pci_epf_test_raise_irq(struct pci_epf_test *epf_test)
245{
246 u8 irq;
247 u8 msi_count;
248 struct pci_epf *epf = epf_test->epf;
249 struct pci_epc *epc = epf->epc;
250 struct pci_epf_test_reg *reg = epf_test->reg[0];
251
252 reg->status |= STATUS_IRQ_RAISED;
253 msi_count = pci_epc_get_msi(epc);
254 irq = (reg->command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT;
255 if (irq > msi_count || msi_count <= 0)
256 pci_epc_raise_irq(epc, PCI_EPC_IRQ_LEGACY, 0);
257 else
258 pci_epc_raise_irq(epc, PCI_EPC_IRQ_MSI, irq);
259}
260
261static void pci_epf_test_cmd_handler(struct work_struct *work)
262{
263 int ret;
264 u8 irq;
265 u8 msi_count;
266 struct pci_epf_test *epf_test = container_of(work, struct pci_epf_test,
267 cmd_handler.work);
268 struct pci_epf *epf = epf_test->epf;
269 struct pci_epc *epc = epf->epc;
270 struct pci_epf_test_reg *reg = epf_test->reg[0];
271
272 if (!reg->command)
273 goto reset_handler;
274
275 if (reg->command & COMMAND_RAISE_LEGACY_IRQ) {
276 reg->status = STATUS_IRQ_RAISED;
277 pci_epc_raise_irq(epc, PCI_EPC_IRQ_LEGACY, 0);
278 goto reset_handler;
279 }
280
281 if (reg->command & COMMAND_WRITE) {
282 ret = pci_epf_test_write(epf_test);
283 if (ret)
284 reg->status |= STATUS_WRITE_FAIL;
285 else
286 reg->status |= STATUS_WRITE_SUCCESS;
287 pci_epf_test_raise_irq(epf_test);
288 goto reset_handler;
289 }
290
291 if (reg->command & COMMAND_READ) {
292 ret = pci_epf_test_read(epf_test);
293 if (!ret)
294 reg->status |= STATUS_READ_SUCCESS;
295 else
296 reg->status |= STATUS_READ_FAIL;
297 pci_epf_test_raise_irq(epf_test);
298 goto reset_handler;
299 }
300
301 if (reg->command & COMMAND_COPY) {
302 ret = pci_epf_test_copy(epf_test);
303 if (!ret)
304 reg->status |= STATUS_COPY_SUCCESS;
305 else
306 reg->status |= STATUS_COPY_FAIL;
307 pci_epf_test_raise_irq(epf_test);
308 goto reset_handler;
309 }
310
311 if (reg->command & COMMAND_RAISE_MSI_IRQ) {
312 msi_count = pci_epc_get_msi(epc);
313 irq = (reg->command & MSI_NUMBER_MASK) >> MSI_NUMBER_SHIFT;
314 if (irq > msi_count || msi_count <= 0)
315 goto reset_handler;
316 reg->status = STATUS_IRQ_RAISED;
317 pci_epc_raise_irq(epc, PCI_EPC_IRQ_MSI, irq);
318 goto reset_handler;
319 }
320
321reset_handler:
322 reg->command = 0;
323
324 queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
325 msecs_to_jiffies(1));
326}
327
328static void pci_epf_test_linkup(struct pci_epf *epf)
329{
330 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
331
332 queue_delayed_work(kpcitest_workqueue, &epf_test->cmd_handler,
333 msecs_to_jiffies(1));
334}
335
336static void pci_epf_test_unbind(struct pci_epf *epf)
337{
338 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
339 struct pci_epc *epc = epf->epc;
340 int bar;
341
342 cancel_delayed_work(&epf_test->cmd_handler);
343 pci_epc_stop(epc);
344 for (bar = BAR_0; bar <= BAR_5; bar++) {
345 if (epf_test->reg[bar]) {
346 pci_epf_free_space(epf, epf_test->reg[bar], bar);
347 pci_epc_clear_bar(epc, bar);
348 }
349 }
350}
351
352static int pci_epf_test_set_bar(struct pci_epf *epf)
353{
354 int flags;
355 int bar;
356 int ret;
357 struct pci_epf_bar *epf_bar;
358 struct pci_epc *epc = epf->epc;
359 struct device *dev = &epf->dev;
360 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
361
362 flags = PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_32;
363 if (sizeof(dma_addr_t) == 0x8)
364 flags |= PCI_BASE_ADDRESS_MEM_TYPE_64;
365
366 for (bar = BAR_0; bar <= BAR_5; bar++) {
367 epf_bar = &epf->bar[bar];
368 ret = pci_epc_set_bar(epc, bar, epf_bar->phys_addr,
369 epf_bar->size, flags);
370 if (ret) {
371 pci_epf_free_space(epf, epf_test->reg[bar], bar);
372 dev_err(dev, "failed to set BAR%d\n", bar);
373 if (bar == BAR_0)
374 return ret;
375 }
376 }
377
378 return 0;
379}
380
381static int pci_epf_test_alloc_space(struct pci_epf *epf)
382{
383 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
384 struct device *dev = &epf->dev;
385 void *base;
386 int bar;
387
388 base = pci_epf_alloc_space(epf, sizeof(struct pci_epf_test_reg),
389 BAR_0);
390 if (!base) {
391 dev_err(dev, "failed to allocated register space\n");
392 return -ENOMEM;
393 }
394 epf_test->reg[0] = base;
395
396 for (bar = BAR_1; bar <= BAR_5; bar++) {
397 base = pci_epf_alloc_space(epf, bar_size[bar - 1], bar);
398 if (!base)
399 dev_err(dev, "failed to allocate space for BAR%d\n",
400 bar);
401 epf_test->reg[bar] = base;
402 }
403
404 return 0;
405}
406
407static int pci_epf_test_bind(struct pci_epf *epf)
408{
409 int ret;
410 struct pci_epf_header *header = epf->header;
411 struct pci_epc *epc = epf->epc;
412 struct device *dev = &epf->dev;
413
414 if (WARN_ON_ONCE(!epc))
415 return -EINVAL;
416
417 ret = pci_epc_write_header(epc, header);
418 if (ret) {
419 dev_err(dev, "configuration header write failed\n");
420 return ret;
421 }
422
423 ret = pci_epf_test_alloc_space(epf);
424 if (ret)
425 return ret;
426
427 ret = pci_epf_test_set_bar(epf);
428 if (ret)
429 return ret;
430
431 ret = pci_epc_set_msi(epc, epf->msi_interrupts);
432 if (ret)
433 return ret;
434
435 return 0;
436}
437
438static int pci_epf_test_probe(struct pci_epf *epf)
439{
440 struct pci_epf_test *epf_test;
441 struct device *dev = &epf->dev;
442
443 epf_test = devm_kzalloc(dev, sizeof(*epf_test), GFP_KERNEL);
444 if (!epf_test)
445 return -ENOMEM;
446
447 epf->header = &test_header;
448 epf_test->epf = epf;
449
450 INIT_DELAYED_WORK(&epf_test->cmd_handler, pci_epf_test_cmd_handler);
451
452 epf_set_drvdata(epf, epf_test);
453 return 0;
454}
455
456static int pci_epf_test_remove(struct pci_epf *epf)
457{
458 struct pci_epf_test *epf_test = epf_get_drvdata(epf);
459
460 kfree(epf_test);
461 return 0;
462}
463
464static struct pci_epf_ops ops = {
465 .unbind = pci_epf_test_unbind,
466 .bind = pci_epf_test_bind,
467 .linkup = pci_epf_test_linkup,
468};
469
470static const struct pci_epf_device_id pci_epf_test_ids[] = {
471 {
472 .name = "pci_epf_test",
473 },
474 {},
475};
476
477static struct pci_epf_driver test_driver = {
478 .driver.name = "pci_epf_test",
479 .probe = pci_epf_test_probe,
480 .remove = pci_epf_test_remove,
481 .id_table = pci_epf_test_ids,
482 .ops = &ops,
483 .owner = THIS_MODULE,
484};
485
486static int __init pci_epf_test_init(void)
487{
488 int ret;
489
490 kpcitest_workqueue = alloc_workqueue("kpcitest",
491 WQ_MEM_RECLAIM | WQ_HIGHPRI, 0);
492 ret = pci_epf_register_driver(&test_driver);
493 if (ret) {
494 pr_err("failed to register pci epf test driver --> %d\n", ret);
495 return ret;
496 }
497
498 return 0;
499}
500module_init(pci_epf_test_init);
501
502static void __exit pci_epf_test_exit(void)
503{
504 pci_epf_unregister_driver(&test_driver);
505}
506module_exit(pci_epf_test_exit);
507
508MODULE_DESCRIPTION("PCI EPF TEST DRIVER");
509MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
510MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/endpoint/pci-ep-cfs.c b/drivers/pci/endpoint/pci-ep-cfs.c
new file mode 100644
index 000000000000..424fdd6ed1ca
--- /dev/null
+++ b/drivers/pci/endpoint/pci-ep-cfs.c
@@ -0,0 +1,509 @@
1/**
2 * configfs to configure the PCI endpoint
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/module.h>
21#include <linux/slab.h>
22
23#include <linux/pci-epc.h>
24#include <linux/pci-epf.h>
25#include <linux/pci-ep-cfs.h>
26
27static struct config_group *functions_group;
28static struct config_group *controllers_group;
29
30struct pci_epf_group {
31 struct config_group group;
32 struct pci_epf *epf;
33};
34
35struct pci_epc_group {
36 struct config_group group;
37 struct pci_epc *epc;
38 bool start;
39 unsigned long function_num_map;
40};
41
42static inline struct pci_epf_group *to_pci_epf_group(struct config_item *item)
43{
44 return container_of(to_config_group(item), struct pci_epf_group, group);
45}
46
47static inline struct pci_epc_group *to_pci_epc_group(struct config_item *item)
48{
49 return container_of(to_config_group(item), struct pci_epc_group, group);
50}
51
52static ssize_t pci_epc_start_store(struct config_item *item, const char *page,
53 size_t len)
54{
55 int ret;
56 bool start;
57 struct pci_epc *epc;
58 struct pci_epc_group *epc_group = to_pci_epc_group(item);
59
60 epc = epc_group->epc;
61
62 ret = kstrtobool(page, &start);
63 if (ret)
64 return ret;
65
66 if (!start) {
67 pci_epc_stop(epc);
68 return len;
69 }
70
71 ret = pci_epc_start(epc);
72 if (ret) {
73 dev_err(&epc->dev, "failed to start endpoint controller\n");
74 return -EINVAL;
75 }
76
77 epc_group->start = start;
78
79 return len;
80}
81
82static ssize_t pci_epc_start_show(struct config_item *item, char *page)
83{
84 return sprintf(page, "%d\n",
85 to_pci_epc_group(item)->start);
86}
87
88CONFIGFS_ATTR(pci_epc_, start);
89
90static struct configfs_attribute *pci_epc_attrs[] = {
91 &pci_epc_attr_start,
92 NULL,
93};
94
95static int pci_epc_epf_link(struct config_item *epc_item,
96 struct config_item *epf_item)
97{
98 int ret;
99 u32 func_no = 0;
100 struct pci_epc *epc;
101 struct pci_epf *epf;
102 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
103 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
104
105 epc = epc_group->epc;
106 epf = epf_group->epf;
107 ret = pci_epc_add_epf(epc, epf);
108 if (ret)
109 goto err_add_epf;
110
111 func_no = find_first_zero_bit(&epc_group->function_num_map,
112 sizeof(epc_group->function_num_map));
113 set_bit(func_no, &epc_group->function_num_map);
114 epf->func_no = func_no;
115
116 ret = pci_epf_bind(epf);
117 if (ret)
118 goto err_epf_bind;
119
120 return 0;
121
122err_epf_bind:
123 pci_epc_remove_epf(epc, epf);
124
125err_add_epf:
126 clear_bit(func_no, &epc_group->function_num_map);
127
128 return ret;
129}
130
131static void pci_epc_epf_unlink(struct config_item *epc_item,
132 struct config_item *epf_item)
133{
134 struct pci_epc *epc;
135 struct pci_epf *epf;
136 struct pci_epf_group *epf_group = to_pci_epf_group(epf_item);
137 struct pci_epc_group *epc_group = to_pci_epc_group(epc_item);
138
139 WARN_ON_ONCE(epc_group->start);
140
141 epc = epc_group->epc;
142 epf = epf_group->epf;
143 clear_bit(epf->func_no, &epc_group->function_num_map);
144 pci_epf_unbind(epf);
145 pci_epc_remove_epf(epc, epf);
146}
147
148static struct configfs_item_operations pci_epc_item_ops = {
149 .allow_link = pci_epc_epf_link,
150 .drop_link = pci_epc_epf_unlink,
151};
152
153static struct config_item_type pci_epc_type = {
154 .ct_item_ops = &pci_epc_item_ops,
155 .ct_attrs = pci_epc_attrs,
156 .ct_owner = THIS_MODULE,
157};
158
159struct config_group *pci_ep_cfs_add_epc_group(const char *name)
160{
161 int ret;
162 struct pci_epc *epc;
163 struct config_group *group;
164 struct pci_epc_group *epc_group;
165
166 epc_group = kzalloc(sizeof(*epc_group), GFP_KERNEL);
167 if (!epc_group) {
168 ret = -ENOMEM;
169 goto err;
170 }
171
172 group = &epc_group->group;
173
174 config_group_init_type_name(group, name, &pci_epc_type);
175 ret = configfs_register_group(controllers_group, group);
176 if (ret) {
177 pr_err("failed to register configfs group for %s\n", name);
178 goto err_register_group;
179 }
180
181 epc = pci_epc_get(name);
182 if (IS_ERR(epc)) {
183 ret = PTR_ERR(epc);
184 goto err_epc_get;
185 }
186
187 epc_group->epc = epc;
188
189 return group;
190
191err_epc_get:
192 configfs_unregister_group(group);
193
194err_register_group:
195 kfree(epc_group);
196
197err:
198 return ERR_PTR(ret);
199}
200EXPORT_SYMBOL(pci_ep_cfs_add_epc_group);
201
202void pci_ep_cfs_remove_epc_group(struct config_group *group)
203{
204 struct pci_epc_group *epc_group;
205
206 if (!group)
207 return;
208
209 epc_group = container_of(group, struct pci_epc_group, group);
210 pci_epc_put(epc_group->epc);
211 configfs_unregister_group(&epc_group->group);
212 kfree(epc_group);
213}
214EXPORT_SYMBOL(pci_ep_cfs_remove_epc_group);
215
216#define PCI_EPF_HEADER_R(_name) \
217static ssize_t pci_epf_##_name##_show(struct config_item *item, char *page) \
218{ \
219 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
220 if (WARN_ON_ONCE(!epf->header)) \
221 return -EINVAL; \
222 return sprintf(page, "0x%04x\n", epf->header->_name); \
223}
224
225#define PCI_EPF_HEADER_W_u32(_name) \
226static ssize_t pci_epf_##_name##_store(struct config_item *item, \
227 const char *page, size_t len) \
228{ \
229 u32 val; \
230 int ret; \
231 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
232 if (WARN_ON_ONCE(!epf->header)) \
233 return -EINVAL; \
234 ret = kstrtou32(page, 0, &val); \
235 if (ret) \
236 return ret; \
237 epf->header->_name = val; \
238 return len; \
239}
240
241#define PCI_EPF_HEADER_W_u16(_name) \
242static ssize_t pci_epf_##_name##_store(struct config_item *item, \
243 const char *page, size_t len) \
244{ \
245 u16 val; \
246 int ret; \
247 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
248 if (WARN_ON_ONCE(!epf->header)) \
249 return -EINVAL; \
250 ret = kstrtou16(page, 0, &val); \
251 if (ret) \
252 return ret; \
253 epf->header->_name = val; \
254 return len; \
255}
256
257#define PCI_EPF_HEADER_W_u8(_name) \
258static ssize_t pci_epf_##_name##_store(struct config_item *item, \
259 const char *page, size_t len) \
260{ \
261 u8 val; \
262 int ret; \
263 struct pci_epf *epf = to_pci_epf_group(item)->epf; \
264 if (WARN_ON_ONCE(!epf->header)) \
265 return -EINVAL; \
266 ret = kstrtou8(page, 0, &val); \
267 if (ret) \
268 return ret; \
269 epf->header->_name = val; \
270 return len; \
271}
272
273static ssize_t pci_epf_msi_interrupts_store(struct config_item *item,
274 const char *page, size_t len)
275{
276 u8 val;
277 int ret;
278
279 ret = kstrtou8(page, 0, &val);
280 if (ret)
281 return ret;
282
283 to_pci_epf_group(item)->epf->msi_interrupts = val;
284
285 return len;
286}
287
288static ssize_t pci_epf_msi_interrupts_show(struct config_item *item,
289 char *page)
290{
291 return sprintf(page, "%d\n",
292 to_pci_epf_group(item)->epf->msi_interrupts);
293}
294
295PCI_EPF_HEADER_R(vendorid)
296PCI_EPF_HEADER_W_u16(vendorid)
297
298PCI_EPF_HEADER_R(deviceid)
299PCI_EPF_HEADER_W_u16(deviceid)
300
301PCI_EPF_HEADER_R(revid)
302PCI_EPF_HEADER_W_u8(revid)
303
304PCI_EPF_HEADER_R(progif_code)
305PCI_EPF_HEADER_W_u8(progif_code)
306
307PCI_EPF_HEADER_R(subclass_code)
308PCI_EPF_HEADER_W_u8(subclass_code)
309
310PCI_EPF_HEADER_R(baseclass_code)
311PCI_EPF_HEADER_W_u8(baseclass_code)
312
313PCI_EPF_HEADER_R(cache_line_size)
314PCI_EPF_HEADER_W_u8(cache_line_size)
315
316PCI_EPF_HEADER_R(subsys_vendor_id)
317PCI_EPF_HEADER_W_u16(subsys_vendor_id)
318
319PCI_EPF_HEADER_R(subsys_id)
320PCI_EPF_HEADER_W_u16(subsys_id)
321
322PCI_EPF_HEADER_R(interrupt_pin)
323PCI_EPF_HEADER_W_u8(interrupt_pin)
324
325CONFIGFS_ATTR(pci_epf_, vendorid);
326CONFIGFS_ATTR(pci_epf_, deviceid);
327CONFIGFS_ATTR(pci_epf_, revid);
328CONFIGFS_ATTR(pci_epf_, progif_code);
329CONFIGFS_ATTR(pci_epf_, subclass_code);
330CONFIGFS_ATTR(pci_epf_, baseclass_code);
331CONFIGFS_ATTR(pci_epf_, cache_line_size);
332CONFIGFS_ATTR(pci_epf_, subsys_vendor_id);
333CONFIGFS_ATTR(pci_epf_, subsys_id);
334CONFIGFS_ATTR(pci_epf_, interrupt_pin);
335CONFIGFS_ATTR(pci_epf_, msi_interrupts);
336
337static struct configfs_attribute *pci_epf_attrs[] = {
338 &pci_epf_attr_vendorid,
339 &pci_epf_attr_deviceid,
340 &pci_epf_attr_revid,
341 &pci_epf_attr_progif_code,
342 &pci_epf_attr_subclass_code,
343 &pci_epf_attr_baseclass_code,
344 &pci_epf_attr_cache_line_size,
345 &pci_epf_attr_subsys_vendor_id,
346 &pci_epf_attr_subsys_id,
347 &pci_epf_attr_interrupt_pin,
348 &pci_epf_attr_msi_interrupts,
349 NULL,
350};
351
352static void pci_epf_release(struct config_item *item)
353{
354 struct pci_epf_group *epf_group = to_pci_epf_group(item);
355
356 pci_epf_destroy(epf_group->epf);
357 kfree(epf_group);
358}
359
360static struct configfs_item_operations pci_epf_ops = {
361 .release = pci_epf_release,
362};
363
364static struct config_item_type pci_epf_type = {
365 .ct_item_ops = &pci_epf_ops,
366 .ct_attrs = pci_epf_attrs,
367 .ct_owner = THIS_MODULE,
368};
369
370static struct config_group *pci_epf_make(struct config_group *group,
371 const char *name)
372{
373 struct pci_epf_group *epf_group;
374 struct pci_epf *epf;
375
376 epf_group = kzalloc(sizeof(*epf_group), GFP_KERNEL);
377 if (!epf_group)
378 return ERR_PTR(-ENOMEM);
379
380 config_group_init_type_name(&epf_group->group, name, &pci_epf_type);
381
382 epf = pci_epf_create(group->cg_item.ci_name);
383 if (IS_ERR(epf)) {
384 pr_err("failed to create endpoint function device\n");
385 return ERR_PTR(-EINVAL);
386 }
387
388 epf_group->epf = epf;
389
390 return &epf_group->group;
391}
392
393static void pci_epf_drop(struct config_group *group, struct config_item *item)
394{
395 config_item_put(item);
396}
397
398static struct configfs_group_operations pci_epf_group_ops = {
399 .make_group = &pci_epf_make,
400 .drop_item = &pci_epf_drop,
401};
402
403static struct config_item_type pci_epf_group_type = {
404 .ct_group_ops = &pci_epf_group_ops,
405 .ct_owner = THIS_MODULE,
406};
407
408struct config_group *pci_ep_cfs_add_epf_group(const char *name)
409{
410 struct config_group *group;
411
412 group = configfs_register_default_group(functions_group, name,
413 &pci_epf_group_type);
414 if (IS_ERR(group))
415 pr_err("failed to register configfs group for %s function\n",
416 name);
417
418 return group;
419}
420EXPORT_SYMBOL(pci_ep_cfs_add_epf_group);
421
422void pci_ep_cfs_remove_epf_group(struct config_group *group)
423{
424 if (IS_ERR_OR_NULL(group))
425 return;
426
427 configfs_unregister_default_group(group);
428}
429EXPORT_SYMBOL(pci_ep_cfs_remove_epf_group);
430
431static struct config_item_type pci_functions_type = {
432 .ct_owner = THIS_MODULE,
433};
434
435static struct config_item_type pci_controllers_type = {
436 .ct_owner = THIS_MODULE,
437};
438
439static struct config_item_type pci_ep_type = {
440 .ct_owner = THIS_MODULE,
441};
442
443static struct configfs_subsystem pci_ep_cfs_subsys = {
444 .su_group = {
445 .cg_item = {
446 .ci_namebuf = "pci_ep",
447 .ci_type = &pci_ep_type,
448 },
449 },
450 .su_mutex = __MUTEX_INITIALIZER(pci_ep_cfs_subsys.su_mutex),
451};
452
453static int __init pci_ep_cfs_init(void)
454{
455 int ret;
456 struct config_group *root = &pci_ep_cfs_subsys.su_group;
457
458 config_group_init(root);
459
460 ret = configfs_register_subsystem(&pci_ep_cfs_subsys);
461 if (ret) {
462 pr_err("Error %d while registering subsystem %s\n",
463 ret, root->cg_item.ci_namebuf);
464 goto err;
465 }
466
467 functions_group = configfs_register_default_group(root, "functions",
468 &pci_functions_type);
469 if (IS_ERR(functions_group)) {
470 ret = PTR_ERR(functions_group);
471 pr_err("Error %d while registering functions group\n",
472 ret);
473 goto err_functions_group;
474 }
475
476 controllers_group =
477 configfs_register_default_group(root, "controllers",
478 &pci_controllers_type);
479 if (IS_ERR(controllers_group)) {
480 ret = PTR_ERR(controllers_group);
481 pr_err("Error %d while registering controllers group\n",
482 ret);
483 goto err_controllers_group;
484 }
485
486 return 0;
487
488err_controllers_group:
489 configfs_unregister_default_group(functions_group);
490
491err_functions_group:
492 configfs_unregister_subsystem(&pci_ep_cfs_subsys);
493
494err:
495 return ret;
496}
497module_init(pci_ep_cfs_init);
498
499static void __exit pci_ep_cfs_exit(void)
500{
501 configfs_unregister_default_group(controllers_group);
502 configfs_unregister_default_group(functions_group);
503 configfs_unregister_subsystem(&pci_ep_cfs_subsys);
504}
505module_exit(pci_ep_cfs_exit);
506
507MODULE_DESCRIPTION("PCI EP CONFIGFS");
508MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
509MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/endpoint/pci-epc-core.c b/drivers/pci/endpoint/pci-epc-core.c
new file mode 100644
index 000000000000..caa7be10e473
--- /dev/null
+++ b/drivers/pci/endpoint/pci-epc-core.c
@@ -0,0 +1,580 @@
1/**
2 * PCI Endpoint *Controller* (EPC) library
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/device.h>
21#include <linux/dma-mapping.h>
22#include <linux/slab.h>
23#include <linux/module.h>
24
25#include <linux/pci-epc.h>
26#include <linux/pci-epf.h>
27#include <linux/pci-ep-cfs.h>
28
29static struct class *pci_epc_class;
30
31static void devm_pci_epc_release(struct device *dev, void *res)
32{
33 struct pci_epc *epc = *(struct pci_epc **)res;
34
35 pci_epc_destroy(epc);
36}
37
38static int devm_pci_epc_match(struct device *dev, void *res, void *match_data)
39{
40 struct pci_epc **epc = res;
41
42 return *epc == match_data;
43}
44
45/**
46 * pci_epc_put() - release the PCI endpoint controller
47 * @epc: epc returned by pci_epc_get()
48 *
49 * release the refcount the caller obtained by invoking pci_epc_get()
50 */
51void pci_epc_put(struct pci_epc *epc)
52{
53 if (!epc || IS_ERR(epc))
54 return;
55
56 module_put(epc->ops->owner);
57 put_device(&epc->dev);
58}
59EXPORT_SYMBOL_GPL(pci_epc_put);
60
61/**
62 * pci_epc_get() - get the PCI endpoint controller
63 * @epc_name: device name of the endpoint controller
64 *
65 * Invoke to get struct pci_epc * corresponding to the device name of the
66 * endpoint controller
67 */
68struct pci_epc *pci_epc_get(const char *epc_name)
69{
70 int ret = -EINVAL;
71 struct pci_epc *epc;
72 struct device *dev;
73 struct class_dev_iter iter;
74
75 class_dev_iter_init(&iter, pci_epc_class, NULL, NULL);
76 while ((dev = class_dev_iter_next(&iter))) {
77 if (strcmp(epc_name, dev_name(dev)))
78 continue;
79
80 epc = to_pci_epc(dev);
81 if (!try_module_get(epc->ops->owner)) {
82 ret = -EINVAL;
83 goto err;
84 }
85
86 class_dev_iter_exit(&iter);
87 get_device(&epc->dev);
88 return epc;
89 }
90
91err:
92 class_dev_iter_exit(&iter);
93 return ERR_PTR(ret);
94}
95EXPORT_SYMBOL_GPL(pci_epc_get);
96
97/**
98 * pci_epc_stop() - stop the PCI link
99 * @epc: the link of the EPC device that has to be stopped
100 *
101 * Invoke to stop the PCI link
102 */
103void pci_epc_stop(struct pci_epc *epc)
104{
105 unsigned long flags;
106
107 if (IS_ERR(epc) || !epc->ops->stop)
108 return;
109
110 spin_lock_irqsave(&epc->lock, flags);
111 epc->ops->stop(epc);
112 spin_unlock_irqrestore(&epc->lock, flags);
113}
114EXPORT_SYMBOL_GPL(pci_epc_stop);
115
116/**
117 * pci_epc_start() - start the PCI link
118 * @epc: the link of *this* EPC device has to be started
119 *
120 * Invoke to start the PCI link
121 */
122int pci_epc_start(struct pci_epc *epc)
123{
124 int ret;
125 unsigned long flags;
126
127 if (IS_ERR(epc))
128 return -EINVAL;
129
130 if (!epc->ops->start)
131 return 0;
132
133 spin_lock_irqsave(&epc->lock, flags);
134 ret = epc->ops->start(epc);
135 spin_unlock_irqrestore(&epc->lock, flags);
136
137 return ret;
138}
139EXPORT_SYMBOL_GPL(pci_epc_start);
140
141/**
142 * pci_epc_raise_irq() - interrupt the host system
143 * @epc: the EPC device which has to interrupt the host
144 * @type: specify the type of interrupt; legacy or MSI
145 * @interrupt_num: the MSI interrupt number
146 *
147 * Invoke to raise an MSI or legacy interrupt
148 */
149int pci_epc_raise_irq(struct pci_epc *epc, enum pci_epc_irq_type type,
150 u8 interrupt_num)
151{
152 int ret;
153 unsigned long flags;
154
155 if (IS_ERR(epc))
156 return -EINVAL;
157
158 if (!epc->ops->raise_irq)
159 return 0;
160
161 spin_lock_irqsave(&epc->lock, flags);
162 ret = epc->ops->raise_irq(epc, type, interrupt_num);
163 spin_unlock_irqrestore(&epc->lock, flags);
164
165 return ret;
166}
167EXPORT_SYMBOL_GPL(pci_epc_raise_irq);
168
169/**
170 * pci_epc_get_msi() - get the number of MSI interrupt numbers allocated
171 * @epc: the EPC device to which MSI interrupts was requested
172 *
173 * Invoke to get the number of MSI interrupts allocated by the RC
174 */
175int pci_epc_get_msi(struct pci_epc *epc)
176{
177 int interrupt;
178 unsigned long flags;
179
180 if (IS_ERR(epc))
181 return 0;
182
183 if (!epc->ops->get_msi)
184 return 0;
185
186 spin_lock_irqsave(&epc->lock, flags);
187 interrupt = epc->ops->get_msi(epc);
188 spin_unlock_irqrestore(&epc->lock, flags);
189
190 if (interrupt < 0)
191 return 0;
192
193 interrupt = 1 << interrupt;
194
195 return interrupt;
196}
197EXPORT_SYMBOL_GPL(pci_epc_get_msi);
198
199/**
200 * pci_epc_set_msi() - set the number of MSI interrupt numbers required
201 * @epc: the EPC device on which MSI has to be configured
202 * @interrupts: number of MSI interrupts required by the EPF
203 *
204 * Invoke to set the required number of MSI interrupts.
205 */
206int pci_epc_set_msi(struct pci_epc *epc, u8 interrupts)
207{
208 int ret;
209 u8 encode_int;
210 unsigned long flags;
211
212 if (IS_ERR(epc))
213 return -EINVAL;
214
215 if (!epc->ops->set_msi)
216 return 0;
217
218 encode_int = order_base_2(interrupts);
219
220 spin_lock_irqsave(&epc->lock, flags);
221 ret = epc->ops->set_msi(epc, encode_int);
222 spin_unlock_irqrestore(&epc->lock, flags);
223
224 return ret;
225}
226EXPORT_SYMBOL_GPL(pci_epc_set_msi);
227
228/**
229 * pci_epc_unmap_addr() - unmap CPU address from PCI address
230 * @epc: the EPC device on which address is allocated
231 * @phys_addr: physical address of the local system
232 *
233 * Invoke to unmap the CPU address from PCI address.
234 */
235void pci_epc_unmap_addr(struct pci_epc *epc, phys_addr_t phys_addr)
236{
237 unsigned long flags;
238
239 if (IS_ERR(epc))
240 return;
241
242 if (!epc->ops->unmap_addr)
243 return;
244
245 spin_lock_irqsave(&epc->lock, flags);
246 epc->ops->unmap_addr(epc, phys_addr);
247 spin_unlock_irqrestore(&epc->lock, flags);
248}
249EXPORT_SYMBOL_GPL(pci_epc_unmap_addr);
250
251/**
252 * pci_epc_map_addr() - map CPU address to PCI address
253 * @epc: the EPC device on which address is allocated
254 * @phys_addr: physical address of the local system
255 * @pci_addr: PCI address to which the physical address should be mapped
256 * @size: the size of the allocation
257 *
258 * Invoke to map CPU address with PCI address.
259 */
260int pci_epc_map_addr(struct pci_epc *epc, phys_addr_t phys_addr,
261 u64 pci_addr, size_t size)
262{
263 int ret;
264 unsigned long flags;
265
266 if (IS_ERR(epc))
267 return -EINVAL;
268
269 if (!epc->ops->map_addr)
270 return 0;
271
272 spin_lock_irqsave(&epc->lock, flags);
273 ret = epc->ops->map_addr(epc, phys_addr, pci_addr, size);
274 spin_unlock_irqrestore(&epc->lock, flags);
275
276 return ret;
277}
278EXPORT_SYMBOL_GPL(pci_epc_map_addr);
279
280/**
281 * pci_epc_clear_bar() - reset the BAR
282 * @epc: the EPC device for which the BAR has to be cleared
283 * @bar: the BAR number that has to be reset
284 *
285 * Invoke to reset the BAR of the endpoint device.
286 */
287void pci_epc_clear_bar(struct pci_epc *epc, int bar)
288{
289 unsigned long flags;
290
291 if (IS_ERR(epc))
292 return;
293
294 if (!epc->ops->clear_bar)
295 return;
296
297 spin_lock_irqsave(&epc->lock, flags);
298 epc->ops->clear_bar(epc, bar);
299 spin_unlock_irqrestore(&epc->lock, flags);
300}
301EXPORT_SYMBOL_GPL(pci_epc_clear_bar);
302
303/**
304 * pci_epc_set_bar() - configure BAR in order for host to assign PCI addr space
305 * @epc: the EPC device on which BAR has to be configured
306 * @bar: the BAR number that has to be configured
307 * @size: the size of the addr space
308 * @flags: specify memory allocation/io allocation/32bit address/64 bit address
309 *
310 * Invoke to configure the BAR of the endpoint device.
311 */
312int pci_epc_set_bar(struct pci_epc *epc, enum pci_barno bar,
313 dma_addr_t bar_phys, size_t size, int flags)
314{
315 int ret;
316 unsigned long irq_flags;
317
318 if (IS_ERR(epc))
319 return -EINVAL;
320
321 if (!epc->ops->set_bar)
322 return 0;
323
324 spin_lock_irqsave(&epc->lock, irq_flags);
325 ret = epc->ops->set_bar(epc, bar, bar_phys, size, flags);
326 spin_unlock_irqrestore(&epc->lock, irq_flags);
327
328 return ret;
329}
330EXPORT_SYMBOL_GPL(pci_epc_set_bar);
331
332/**
333 * pci_epc_write_header() - write standard configuration header
334 * @epc: the EPC device to which the configuration header should be written
335 * @header: standard configuration header fields
336 *
337 * Invoke to write the configuration header to the endpoint controller. Every
338 * endpoint controller will have a dedicated location to which the standard
339 * configuration header would be written. The callback function should write
340 * the header fields to this dedicated location.
341 */
342int pci_epc_write_header(struct pci_epc *epc, struct pci_epf_header *header)
343{
344 int ret;
345 unsigned long flags;
346
347 if (IS_ERR(epc))
348 return -EINVAL;
349
350 if (!epc->ops->write_header)
351 return 0;
352
353 spin_lock_irqsave(&epc->lock, flags);
354 ret = epc->ops->write_header(epc, header);
355 spin_unlock_irqrestore(&epc->lock, flags);
356
357 return ret;
358}
359EXPORT_SYMBOL_GPL(pci_epc_write_header);
360
361/**
362 * pci_epc_add_epf() - bind PCI endpoint function to an endpoint controller
363 * @epc: the EPC device to which the endpoint function should be added
364 * @epf: the endpoint function to be added
365 *
366 * A PCI endpoint device can have one or more functions. In the case of PCIe,
367 * the specification allows up to 8 PCIe endpoint functions. Invoke
368 * pci_epc_add_epf() to add a PCI endpoint function to an endpoint controller.
369 */
370int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf)
371{
372 unsigned long flags;
373
374 if (epf->epc)
375 return -EBUSY;
376
377 if (IS_ERR(epc))
378 return -EINVAL;
379
380 if (epf->func_no > epc->max_functions - 1)
381 return -EINVAL;
382
383 epf->epc = epc;
384 dma_set_coherent_mask(&epf->dev, epc->dev.coherent_dma_mask);
385 epf->dev.dma_mask = epc->dev.dma_mask;
386
387 spin_lock_irqsave(&epc->lock, flags);
388 list_add_tail(&epf->list, &epc->pci_epf);
389 spin_unlock_irqrestore(&epc->lock, flags);
390
391 return 0;
392}
393EXPORT_SYMBOL_GPL(pci_epc_add_epf);
394
395/**
396 * pci_epc_remove_epf() - remove PCI endpoint function from endpoint controller
397 * @epc: the EPC device from which the endpoint function should be removed
398 * @epf: the endpoint function to be removed
399 *
400 * Invoke to remove PCI endpoint function from the endpoint controller.
401 */
402void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf)
403{
404 unsigned long flags;
405
406 if (!epc || IS_ERR(epc))
407 return;
408
409 spin_lock_irqsave(&epc->lock, flags);
410 list_del(&epf->list);
411 spin_unlock_irqrestore(&epc->lock, flags);
412}
413EXPORT_SYMBOL_GPL(pci_epc_remove_epf);
414
415/**
416 * pci_epc_linkup() - Notify the EPF device that EPC device has established a
417 * connection with the Root Complex.
418 * @epc: the EPC device which has established link with the host
419 *
420 * Invoke to Notify the EPF device that the EPC device has established a
421 * connection with the Root Complex.
422 */
423void pci_epc_linkup(struct pci_epc *epc)
424{
425 unsigned long flags;
426 struct pci_epf *epf;
427
428 if (!epc || IS_ERR(epc))
429 return;
430
431 spin_lock_irqsave(&epc->lock, flags);
432 list_for_each_entry(epf, &epc->pci_epf, list)
433 pci_epf_linkup(epf);
434 spin_unlock_irqrestore(&epc->lock, flags);
435}
436EXPORT_SYMBOL_GPL(pci_epc_linkup);
437
438/**
439 * pci_epc_destroy() - destroy the EPC device
440 * @epc: the EPC device that has to be destroyed
441 *
442 * Invoke to destroy the PCI EPC device
443 */
444void pci_epc_destroy(struct pci_epc *epc)
445{
446 pci_ep_cfs_remove_epc_group(epc->group);
447 device_unregister(&epc->dev);
448 kfree(epc);
449}
450EXPORT_SYMBOL_GPL(pci_epc_destroy);
451
452/**
453 * devm_pci_epc_destroy() - destroy the EPC device
454 * @dev: device that wants to destroy the EPC
455 * @epc: the EPC device that has to be destroyed
456 *
457 * Invoke to destroy the devres associated with this
458 * pci_epc and destroy the EPC device.
459 */
460void devm_pci_epc_destroy(struct device *dev, struct pci_epc *epc)
461{
462 int r;
463
464 r = devres_destroy(dev, devm_pci_epc_release, devm_pci_epc_match,
465 epc);
466 dev_WARN_ONCE(dev, r, "couldn't find PCI EPC resource\n");
467}
468EXPORT_SYMBOL_GPL(devm_pci_epc_destroy);
469
470/**
471 * __pci_epc_create() - create a new endpoint controller (EPC) device
472 * @dev: device that is creating the new EPC
473 * @ops: function pointers for performing EPC operations
474 * @owner: the owner of the module that creates the EPC device
475 *
476 * Invoke to create a new EPC device and add it to pci_epc class.
477 */
478struct pci_epc *
479__pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
480 struct module *owner)
481{
482 int ret;
483 struct pci_epc *epc;
484
485 if (WARN_ON(!dev)) {
486 ret = -EINVAL;
487 goto err_ret;
488 }
489
490 epc = kzalloc(sizeof(*epc), GFP_KERNEL);
491 if (!epc) {
492 ret = -ENOMEM;
493 goto err_ret;
494 }
495
496 spin_lock_init(&epc->lock);
497 INIT_LIST_HEAD(&epc->pci_epf);
498
499 device_initialize(&epc->dev);
500 dma_set_coherent_mask(&epc->dev, dev->coherent_dma_mask);
501 epc->dev.class = pci_epc_class;
502 epc->dev.dma_mask = dev->dma_mask;
503 epc->ops = ops;
504
505 ret = dev_set_name(&epc->dev, "%s", dev_name(dev));
506 if (ret)
507 goto put_dev;
508
509 ret = device_add(&epc->dev);
510 if (ret)
511 goto put_dev;
512
513 epc->group = pci_ep_cfs_add_epc_group(dev_name(dev));
514
515 return epc;
516
517put_dev:
518 put_device(&epc->dev);
519 kfree(epc);
520
521err_ret:
522 return ERR_PTR(ret);
523}
524EXPORT_SYMBOL_GPL(__pci_epc_create);
525
526/**
527 * __devm_pci_epc_create() - create a new endpoint controller (EPC) device
528 * @dev: device that is creating the new EPC
529 * @ops: function pointers for performing EPC operations
530 * @owner: the owner of the module that creates the EPC device
531 *
532 * Invoke to create a new EPC device and add it to pci_epc class.
533 * While at that, it also associates the device with the pci_epc using devres.
534 * On driver detach, release function is invoked on the devres data,
535 * then, devres data is freed.
536 */
537struct pci_epc *
538__devm_pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
539 struct module *owner)
540{
541 struct pci_epc **ptr, *epc;
542
543 ptr = devres_alloc(devm_pci_epc_release, sizeof(*ptr), GFP_KERNEL);
544 if (!ptr)
545 return ERR_PTR(-ENOMEM);
546
547 epc = __pci_epc_create(dev, ops, owner);
548 if (!IS_ERR(epc)) {
549 *ptr = epc;
550 devres_add(dev, ptr);
551 } else {
552 devres_free(ptr);
553 }
554
555 return epc;
556}
557EXPORT_SYMBOL_GPL(__devm_pci_epc_create);
558
559static int __init pci_epc_init(void)
560{
561 pci_epc_class = class_create(THIS_MODULE, "pci_epc");
562 if (IS_ERR(pci_epc_class)) {
563 pr_err("failed to create pci epc class --> %ld\n",
564 PTR_ERR(pci_epc_class));
565 return PTR_ERR(pci_epc_class);
566 }
567
568 return 0;
569}
570module_init(pci_epc_init);
571
572static void __exit pci_epc_exit(void)
573{
574 class_destroy(pci_epc_class);
575}
576module_exit(pci_epc_exit);
577
578MODULE_DESCRIPTION("PCI EPC Library");
579MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
580MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/endpoint/pci-epc-mem.c b/drivers/pci/endpoint/pci-epc-mem.c
new file mode 100644
index 000000000000..3a94cc1caf22
--- /dev/null
+++ b/drivers/pci/endpoint/pci-epc-mem.c
@@ -0,0 +1,143 @@
1/**
2 * PCI Endpoint *Controller* Address Space Management
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/io.h>
21#include <linux/module.h>
22#include <linux/slab.h>
23
24#include <linux/pci-epc.h>
25
26/**
27 * pci_epc_mem_init() - initialize the pci_epc_mem structure
28 * @epc: the EPC device that invoked pci_epc_mem_init
29 * @phys_base: the physical address of the base
30 * @size: the size of the address space
31 *
32 * Invoke to initialize the pci_epc_mem structure used by the
33 * endpoint functions to allocate mapped PCI address.
34 */
35int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_base, size_t size)
36{
37 int ret;
38 struct pci_epc_mem *mem;
39 unsigned long *bitmap;
40 int pages = size >> PAGE_SHIFT;
41 int bitmap_size = BITS_TO_LONGS(pages) * sizeof(long);
42
43 mem = kzalloc(sizeof(*mem), GFP_KERNEL);
44 if (!mem) {
45 ret = -ENOMEM;
46 goto err;
47 }
48
49 bitmap = kzalloc(bitmap_size, GFP_KERNEL);
50 if (!bitmap) {
51 ret = -ENOMEM;
52 goto err_mem;
53 }
54
55 mem->bitmap = bitmap;
56 mem->phys_base = phys_base;
57 mem->pages = pages;
58 mem->size = size;
59
60 epc->mem = mem;
61
62 return 0;
63
64err_mem:
65 kfree(mem);
66
67err:
68return ret;
69}
70EXPORT_SYMBOL_GPL(pci_epc_mem_init);
71
72/**
73 * pci_epc_mem_exit() - cleanup the pci_epc_mem structure
74 * @epc: the EPC device that invoked pci_epc_mem_exit
75 *
76 * Invoke to cleanup the pci_epc_mem structure allocated in
77 * pci_epc_mem_init().
78 */
79void pci_epc_mem_exit(struct pci_epc *epc)
80{
81 struct pci_epc_mem *mem = epc->mem;
82
83 epc->mem = NULL;
84 kfree(mem->bitmap);
85 kfree(mem);
86}
87EXPORT_SYMBOL_GPL(pci_epc_mem_exit);
88
89/**
90 * pci_epc_mem_alloc_addr() - allocate memory address from EPC addr space
91 * @epc: the EPC device on which memory has to be allocated
92 * @phys_addr: populate the allocated physical address here
93 * @size: the size of the address space that has to be allocated
94 *
95 * Invoke to allocate memory address from the EPC address space. This
96 * is usually done to map the remote RC address into the local system.
97 */
98void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
99 phys_addr_t *phys_addr, size_t size)
100{
101 int pageno;
102 void __iomem *virt_addr;
103 struct pci_epc_mem *mem = epc->mem;
104 int order = get_order(size);
105
106 pageno = bitmap_find_free_region(mem->bitmap, mem->pages, order);
107 if (pageno < 0)
108 return NULL;
109
110 *phys_addr = mem->phys_base + (pageno << PAGE_SHIFT);
111 virt_addr = ioremap(*phys_addr, size);
112 if (!virt_addr)
113 bitmap_release_region(mem->bitmap, pageno, order);
114
115 return virt_addr;
116}
117EXPORT_SYMBOL_GPL(pci_epc_mem_alloc_addr);
118
119/**
120 * pci_epc_mem_free_addr() - free the allocated memory address
121 * @epc: the EPC device on which memory was allocated
122 * @phys_addr: the allocated physical address
123 * @virt_addr: virtual address of the allocated mem space
124 * @size: the size of the allocated address space
125 *
126 * Invoke to free the memory allocated using pci_epc_mem_alloc_addr.
127 */
128void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
129 void __iomem *virt_addr, size_t size)
130{
131 int pageno;
132 int order = get_order(size);
133 struct pci_epc_mem *mem = epc->mem;
134
135 iounmap(virt_addr);
136 pageno = (phys_addr - mem->phys_base) >> PAGE_SHIFT;
137 bitmap_release_region(mem->bitmap, pageno, order);
138}
139EXPORT_SYMBOL_GPL(pci_epc_mem_free_addr);
140
141MODULE_DESCRIPTION("PCI EPC Address Space Management");
142MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
143MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/endpoint/pci-epf-core.c b/drivers/pci/endpoint/pci-epf-core.c
new file mode 100644
index 000000000000..6877d6a5bcc9
--- /dev/null
+++ b/drivers/pci/endpoint/pci-epf-core.c
@@ -0,0 +1,359 @@
1/**
2 * PCI Endpoint *Function* (EPF) library
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <linux/device.h>
21#include <linux/dma-mapping.h>
22#include <linux/slab.h>
23#include <linux/module.h>
24
25#include <linux/pci-epc.h>
26#include <linux/pci-epf.h>
27#include <linux/pci-ep-cfs.h>
28
29static struct bus_type pci_epf_bus_type;
30static struct device_type pci_epf_type;
31
32/**
33 * pci_epf_linkup() - Notify the function driver that EPC device has
34 * established a connection with the Root Complex.
35 * @epf: the EPF device bound to the EPC device which has established
36 * the connection with the host
37 *
38 * Invoke to notify the function driver that EPC device has established
39 * a connection with the Root Complex.
40 */
41void pci_epf_linkup(struct pci_epf *epf)
42{
43 if (!epf->driver) {
44 dev_WARN(&epf->dev, "epf device not bound to driver\n");
45 return;
46 }
47
48 epf->driver->ops->linkup(epf);
49}
50EXPORT_SYMBOL_GPL(pci_epf_linkup);
51
52/**
53 * pci_epf_unbind() - Notify the function driver that the binding between the
54 * EPF device and EPC device has been lost
55 * @epf: the EPF device which has lost the binding with the EPC device
56 *
57 * Invoke to notify the function driver that the binding between the EPF device
58 * and EPC device has been lost.
59 */
60void pci_epf_unbind(struct pci_epf *epf)
61{
62 if (!epf->driver) {
63 dev_WARN(&epf->dev, "epf device not bound to driver\n");
64 return;
65 }
66
67 epf->driver->ops->unbind(epf);
68 module_put(epf->driver->owner);
69}
70EXPORT_SYMBOL_GPL(pci_epf_unbind);
71
72/**
73 * pci_epf_bind() - Notify the function driver that the EPF device has been
74 * bound to a EPC device
75 * @epf: the EPF device which has been bound to the EPC device
76 *
77 * Invoke to notify the function driver that it has been bound to a EPC device
78 */
79int pci_epf_bind(struct pci_epf *epf)
80{
81 if (!epf->driver) {
82 dev_WARN(&epf->dev, "epf device not bound to driver\n");
83 return -EINVAL;
84 }
85
86 if (!try_module_get(epf->driver->owner))
87 return -EAGAIN;
88
89 return epf->driver->ops->bind(epf);
90}
91EXPORT_SYMBOL_GPL(pci_epf_bind);
92
93/**
94 * pci_epf_free_space() - free the allocated PCI EPF register space
95 * @addr: the virtual address of the PCI EPF register space
96 * @bar: the BAR number corresponding to the register space
97 *
98 * Invoke to free the allocated PCI EPF register space.
99 */
100void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar)
101{
102 struct device *dev = &epf->dev;
103
104 if (!addr)
105 return;
106
107 dma_free_coherent(dev, epf->bar[bar].size, addr,
108 epf->bar[bar].phys_addr);
109
110 epf->bar[bar].phys_addr = 0;
111 epf->bar[bar].size = 0;
112}
113EXPORT_SYMBOL_GPL(pci_epf_free_space);
114
115/**
116 * pci_epf_alloc_space() - allocate memory for the PCI EPF register space
117 * @size: the size of the memory that has to be allocated
118 * @bar: the BAR number corresponding to the allocated register space
119 *
120 * Invoke to allocate memory for the PCI EPF register space.
121 */
122void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar)
123{
124 void *space;
125 struct device *dev = &epf->dev;
126 dma_addr_t phys_addr;
127
128 if (size < 128)
129 size = 128;
130 size = roundup_pow_of_two(size);
131
132 space = dma_alloc_coherent(dev, size, &phys_addr, GFP_KERNEL);
133 if (!space) {
134 dev_err(dev, "failed to allocate mem space\n");
135 return NULL;
136 }
137
138 epf->bar[bar].phys_addr = phys_addr;
139 epf->bar[bar].size = size;
140
141 return space;
142}
143EXPORT_SYMBOL_GPL(pci_epf_alloc_space);
144
145/**
146 * pci_epf_unregister_driver() - unregister the PCI EPF driver
147 * @driver: the PCI EPF driver that has to be unregistered
148 *
149 * Invoke to unregister the PCI EPF driver.
150 */
151void pci_epf_unregister_driver(struct pci_epf_driver *driver)
152{
153 pci_ep_cfs_remove_epf_group(driver->group);
154 driver_unregister(&driver->driver);
155}
156EXPORT_SYMBOL_GPL(pci_epf_unregister_driver);
157
158/**
159 * __pci_epf_register_driver() - register a new PCI EPF driver
160 * @driver: structure representing PCI EPF driver
161 * @owner: the owner of the module that registers the PCI EPF driver
162 *
163 * Invoke to register a new PCI EPF driver.
164 */
165int __pci_epf_register_driver(struct pci_epf_driver *driver,
166 struct module *owner)
167{
168 int ret;
169
170 if (!driver->ops)
171 return -EINVAL;
172
173 if (!driver->ops->bind || !driver->ops->unbind || !driver->ops->linkup)
174 return -EINVAL;
175
176 driver->driver.bus = &pci_epf_bus_type;
177 driver->driver.owner = owner;
178
179 ret = driver_register(&driver->driver);
180 if (ret)
181 return ret;
182
183 driver->group = pci_ep_cfs_add_epf_group(driver->driver.name);
184
185 return 0;
186}
187EXPORT_SYMBOL_GPL(__pci_epf_register_driver);
188
189/**
190 * pci_epf_destroy() - destroy the created PCI EPF device
191 * @epf: the PCI EPF device that has to be destroyed.
192 *
193 * Invoke to destroy the PCI EPF device created by invoking pci_epf_create().
194 */
195void pci_epf_destroy(struct pci_epf *epf)
196{
197 device_unregister(&epf->dev);
198}
199EXPORT_SYMBOL_GPL(pci_epf_destroy);
200
201/**
202 * pci_epf_create() - create a new PCI EPF device
203 * @name: the name of the PCI EPF device. This name will be used to bind the
204 * the EPF device to a EPF driver
205 *
206 * Invoke to create a new PCI EPF device by providing the name of the function
207 * device.
208 */
209struct pci_epf *pci_epf_create(const char *name)
210{
211 int ret;
212 struct pci_epf *epf;
213 struct device *dev;
214 char *func_name;
215 char *buf;
216
217 epf = kzalloc(sizeof(*epf), GFP_KERNEL);
218 if (!epf) {
219 ret = -ENOMEM;
220 goto err_ret;
221 }
222
223 buf = kstrdup(name, GFP_KERNEL);
224 if (!buf) {
225 ret = -ENOMEM;
226 goto free_epf;
227 }
228
229 func_name = buf;
230 buf = strchrnul(buf, '.');
231 *buf = '\0';
232
233 epf->name = kstrdup(func_name, GFP_KERNEL);
234 if (!epf->name) {
235 ret = -ENOMEM;
236 goto free_func_name;
237 }
238
239 dev = &epf->dev;
240 device_initialize(dev);
241 dev->bus = &pci_epf_bus_type;
242 dev->type = &pci_epf_type;
243
244 ret = dev_set_name(dev, "%s", name);
245 if (ret)
246 goto put_dev;
247
248 ret = device_add(dev);
249 if (ret)
250 goto put_dev;
251
252 kfree(func_name);
253 return epf;
254
255put_dev:
256 put_device(dev);
257 kfree(epf->name);
258
259free_func_name:
260 kfree(func_name);
261
262free_epf:
263 kfree(epf);
264
265err_ret:
266 return ERR_PTR(ret);
267}
268EXPORT_SYMBOL_GPL(pci_epf_create);
269
270static void pci_epf_dev_release(struct device *dev)
271{
272 struct pci_epf *epf = to_pci_epf(dev);
273
274 kfree(epf->name);
275 kfree(epf);
276}
277
278static struct device_type pci_epf_type = {
279 .release = pci_epf_dev_release,
280};
281
282static int
283pci_epf_match_id(const struct pci_epf_device_id *id, const struct pci_epf *epf)
284{
285 while (id->name[0]) {
286 if (strcmp(epf->name, id->name) == 0)
287 return true;
288 id++;
289 }
290
291 return false;
292}
293
294static int pci_epf_device_match(struct device *dev, struct device_driver *drv)
295{
296 struct pci_epf *epf = to_pci_epf(dev);
297 struct pci_epf_driver *driver = to_pci_epf_driver(drv);
298
299 if (driver->id_table)
300 return pci_epf_match_id(driver->id_table, epf);
301
302 return !strcmp(epf->name, drv->name);
303}
304
305static int pci_epf_device_probe(struct device *dev)
306{
307 struct pci_epf *epf = to_pci_epf(dev);
308 struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver);
309
310 if (!driver->probe)
311 return -ENODEV;
312
313 epf->driver = driver;
314
315 return driver->probe(epf);
316}
317
318static int pci_epf_device_remove(struct device *dev)
319{
320 int ret;
321 struct pci_epf *epf = to_pci_epf(dev);
322 struct pci_epf_driver *driver = to_pci_epf_driver(dev->driver);
323
324 ret = driver->remove(epf);
325 epf->driver = NULL;
326
327 return ret;
328}
329
330static struct bus_type pci_epf_bus_type = {
331 .name = "pci-epf",
332 .match = pci_epf_device_match,
333 .probe = pci_epf_device_probe,
334 .remove = pci_epf_device_remove,
335};
336
337static int __init pci_epf_init(void)
338{
339 int ret;
340
341 ret = bus_register(&pci_epf_bus_type);
342 if (ret) {
343 pr_err("failed to register pci epf bus --> %d\n", ret);
344 return ret;
345 }
346
347 return 0;
348}
349module_init(pci_epf_init);
350
351static void __exit pci_epf_exit(void)
352{
353 bus_unregister(&pci_epf_bus_type);
354}
355module_exit(pci_epf_exit);
356
357MODULE_DESCRIPTION("PCI EPF Library");
358MODULE_AUTHOR("Kishon Vijay Abraham I <kishon@ti.com>");
359MODULE_LICENSE("GPL v2");
diff --git a/drivers/pci/host/pci-thunder-pem.c b/drivers/pci/host/pci-thunder-pem.c
index 52b5bdccf5f0..6e031b522529 100644
--- a/drivers/pci/host/pci-thunder-pem.c
+++ b/drivers/pci/host/pci-thunder-pem.c
@@ -14,6 +14,7 @@
14 * Copyright (C) 2015 - 2016 Cavium, Inc. 14 * Copyright (C) 2015 - 2016 Cavium, Inc.
15 */ 15 */
16 16
17#include <linux/bitfield.h>
17#include <linux/kernel.h> 18#include <linux/kernel.h>
18#include <linux/init.h> 19#include <linux/init.h>
19#include <linux/of_address.h> 20#include <linux/of_address.h>
@@ -334,6 +335,49 @@ static int thunder_pem_init(struct device *dev, struct pci_config_window *cfg,
334 335
335#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) 336#if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
336 337
338#define PEM_RES_BASE 0x87e0c0000000UL
339#define PEM_NODE_MASK GENMASK(45, 44)
340#define PEM_INDX_MASK GENMASK(26, 24)
341#define PEM_MIN_DOM_IN_NODE 4
342#define PEM_MAX_DOM_IN_NODE 10
343
344static void thunder_pem_reserve_range(struct device *dev, int seg,
345 struct resource *r)
346{
347 resource_size_t start = r->start, end = r->end;
348 struct resource *res;
349 const char *regionid;
350
351 regionid = kasprintf(GFP_KERNEL, "PEM RC:%d", seg);
352 if (!regionid)
353 return;
354
355 res = request_mem_region(start, end - start + 1, regionid);
356 if (res)
357 res->flags &= ~IORESOURCE_BUSY;
358 else
359 kfree(regionid);
360
361 dev_info(dev, "%pR %s reserved\n", r,
362 res ? "has been" : "could not be");
363}
364
365static void thunder_pem_legacy_fw(struct acpi_pci_root *root,
366 struct resource *res_pem)
367{
368 int node = acpi_get_node(root->device->handle);
369 int index;
370
371 if (node == NUMA_NO_NODE)
372 node = 0;
373
374 index = root->segment - PEM_MIN_DOM_IN_NODE;
375 index -= node * PEM_MAX_DOM_IN_NODE;
376 res_pem->start = PEM_RES_BASE | FIELD_PREP(PEM_NODE_MASK, node) |
377 FIELD_PREP(PEM_INDX_MASK, index);
378 res_pem->flags = IORESOURCE_MEM;
379}
380
337static int thunder_pem_acpi_init(struct pci_config_window *cfg) 381static int thunder_pem_acpi_init(struct pci_config_window *cfg)
338{ 382{
339 struct device *dev = cfg->parent; 383 struct device *dev = cfg->parent;
@@ -346,10 +390,24 @@ static int thunder_pem_acpi_init(struct pci_config_window *cfg)
346 if (!res_pem) 390 if (!res_pem)
347 return -ENOMEM; 391 return -ENOMEM;
348 392
349 ret = acpi_get_rc_resources(dev, "THRX0002", root->segment, res_pem); 393 ret = acpi_get_rc_resources(dev, "CAVA02B", root->segment, res_pem);
394
395 /*
396 * If we fail to gather resources it means that we run with old
397 * FW where we need to calculate PEM-specific resources manually.
398 */
350 if (ret) { 399 if (ret) {
351 dev_err(dev, "can't get rc base address\n"); 400 thunder_pem_legacy_fw(root, res_pem);
352 return ret; 401 /*
402 * Reserve 64K size PEM specific resources. The full 16M range
403 * size is required for thunder_pem_init() call.
404 */
405 res_pem->end = res_pem->start + SZ_64K - 1;
406 thunder_pem_reserve_range(dev, root->segment, res_pem);
407 res_pem->end = res_pem->start + SZ_16M - 1;
408
409 /* Reserve PCI configuration space as well. */
410 thunder_pem_reserve_range(dev, root->segment, &cfg->res);
353 } 411 }
354 412
355 return thunder_pem_init(dev, cfg, res_pem); 413 return thunder_pem_init(dev, cfg, res_pem);
diff --git a/drivers/pci/host/pcie-iproc-bcma.c b/drivers/pci/host/pcie-iproc-bcma.c
index bd4c9ec25edc..384c27e664fe 100644
--- a/drivers/pci/host/pcie-iproc-bcma.c
+++ b/drivers/pci/host/pcie-iproc-bcma.c
@@ -44,8 +44,7 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
44{ 44{
45 struct device *dev = &bdev->dev; 45 struct device *dev = &bdev->dev;
46 struct iproc_pcie *pcie; 46 struct iproc_pcie *pcie;
47 LIST_HEAD(res); 47 LIST_HEAD(resources);
48 struct resource res_mem;
49 int ret; 48 int ret;
50 49
51 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); 50 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
@@ -63,22 +62,23 @@ static int iproc_pcie_bcma_probe(struct bcma_device *bdev)
63 62
64 pcie->base_addr = bdev->addr; 63 pcie->base_addr = bdev->addr;
65 64
66 res_mem.start = bdev->addr_s[0]; 65 pcie->mem.start = bdev->addr_s[0];
67 res_mem.end = bdev->addr_s[0] + SZ_128M - 1; 66 pcie->mem.end = bdev->addr_s[0] + SZ_128M - 1;
68 res_mem.name = "PCIe MEM space"; 67 pcie->mem.name = "PCIe MEM space";
69 res_mem.flags = IORESOURCE_MEM; 68 pcie->mem.flags = IORESOURCE_MEM;
70 pci_add_resource(&res, &res_mem); 69 pci_add_resource(&resources, &pcie->mem);
71 70
72 pcie->map_irq = iproc_pcie_bcma_map_irq; 71 pcie->map_irq = iproc_pcie_bcma_map_irq;
73 72
74 ret = iproc_pcie_setup(pcie, &res); 73 ret = iproc_pcie_setup(pcie, &resources);
75 if (ret) 74 if (ret) {
76 dev_err(dev, "PCIe controller setup failed\n"); 75 dev_err(dev, "PCIe controller setup failed\n");
77 76 pci_free_resource_list(&resources);
78 pci_free_resource_list(&res); 77 return ret;
78 }
79 79
80 bcma_set_drvdata(bdev, pcie); 80 bcma_set_drvdata(bdev, pcie);
81 return ret; 81 return 0;
82} 82}
83 83
84static void iproc_pcie_bcma_remove(struct bcma_device *bdev) 84static void iproc_pcie_bcma_remove(struct bcma_device *bdev)
diff --git a/drivers/pci/host/pcie-iproc-platform.c b/drivers/pci/host/pcie-iproc-platform.c
index f4909bb0b2ad..8c6a327ca6cd 100644
--- a/drivers/pci/host/pcie-iproc-platform.c
+++ b/drivers/pci/host/pcie-iproc-platform.c
@@ -51,7 +51,7 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
51 struct device_node *np = dev->of_node; 51 struct device_node *np = dev->of_node;
52 struct resource reg; 52 struct resource reg;
53 resource_size_t iobase = 0; 53 resource_size_t iobase = 0;
54 LIST_HEAD(res); 54 LIST_HEAD(resources);
55 int ret; 55 int ret;
56 56
57 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL); 57 pcie = devm_kzalloc(dev, sizeof(*pcie), GFP_KERNEL);
@@ -96,10 +96,10 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
96 pcie->phy = NULL; 96 pcie->phy = NULL;
97 } 97 }
98 98
99 ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &iobase); 99 ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &resources,
100 &iobase);
100 if (ret) { 101 if (ret) {
101 dev_err(dev, 102 dev_err(dev, "unable to get PCI host bridge resources\n");
102 "unable to get PCI host bridge resources\n");
103 return ret; 103 return ret;
104 } 104 }
105 105
@@ -112,14 +112,15 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
112 pcie->map_irq = of_irq_parse_and_map_pci; 112 pcie->map_irq = of_irq_parse_and_map_pci;
113 } 113 }
114 114
115 ret = iproc_pcie_setup(pcie, &res); 115 ret = iproc_pcie_setup(pcie, &resources);
116 if (ret) 116 if (ret) {
117 dev_err(dev, "PCIe controller setup failed\n"); 117 dev_err(dev, "PCIe controller setup failed\n");
118 118 pci_free_resource_list(&resources);
119 pci_free_resource_list(&res); 119 return ret;
120 }
120 121
121 platform_set_drvdata(pdev, pcie); 122 platform_set_drvdata(pdev, pcie);
122 return ret; 123 return 0;
123} 124}
124 125
125static int iproc_pcie_pltfm_remove(struct platform_device *pdev) 126static int iproc_pcie_pltfm_remove(struct platform_device *pdev)
diff --git a/drivers/pci/host/pcie-iproc.h b/drivers/pci/host/pcie-iproc.h
index 04fed8e907f1..0bbe2ea44f3e 100644
--- a/drivers/pci/host/pcie-iproc.h
+++ b/drivers/pci/host/pcie-iproc.h
@@ -90,6 +90,7 @@ struct iproc_pcie {
90#ifdef CONFIG_ARM 90#ifdef CONFIG_ARM
91 struct pci_sys_data sysdata; 91 struct pci_sys_data sysdata;
92#endif 92#endif
93 struct resource mem;
93 struct pci_bus *root_bus; 94 struct pci_bus *root_bus;
94 struct phy *phy; 95 struct phy *phy;
95 int (*map_irq)(const struct pci_dev *, u8, u8); 96 int (*map_irq)(const struct pci_dev *, u8, u8);
diff --git a/drivers/pci/pcie/aspm.c b/drivers/pci/pcie/aspm.c
index 973472c23d89..1dfa10cc566b 100644
--- a/drivers/pci/pcie/aspm.c
+++ b/drivers/pci/pcie/aspm.c
@@ -478,7 +478,7 @@ static void aspm_calc_l1ss_info(struct pcie_link_state *link,
478 478
479static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist) 479static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
480{ 480{
481 struct pci_dev *child, *parent = link->pdev; 481 struct pci_dev *child = link->downstream, *parent = link->pdev;
482 struct pci_bus *linkbus = parent->subordinate; 482 struct pci_bus *linkbus = parent->subordinate;
483 struct aspm_register_info upreg, dwreg; 483 struct aspm_register_info upreg, dwreg;
484 484
@@ -491,9 +491,7 @@ static void pcie_aspm_cap_init(struct pcie_link_state *link, int blacklist)
491 491
492 /* Get upstream/downstream components' register state */ 492 /* Get upstream/downstream components' register state */
493 pcie_get_aspm_reg(parent, &upreg); 493 pcie_get_aspm_reg(parent, &upreg);
494 child = pci_function_0(linkbus);
495 pcie_get_aspm_reg(child, &dwreg); 494 pcie_get_aspm_reg(child, &dwreg);
496 link->downstream = child;
497 495
498 /* 496 /*
499 * If ASPM not supported, don't mess with the clocks and link, 497 * If ASPM not supported, don't mess with the clocks and link,
@@ -800,6 +798,7 @@ static struct pcie_link_state *alloc_pcie_link_state(struct pci_dev *pdev)
800 INIT_LIST_HEAD(&link->children); 798 INIT_LIST_HEAD(&link->children);
801 INIT_LIST_HEAD(&link->link); 799 INIT_LIST_HEAD(&link->link);
802 link->pdev = pdev; 800 link->pdev = pdev;
801 link->downstream = pci_function_0(pdev->subordinate);
803 802
804 /* 803 /*
805 * Root Ports and PCI/PCI-X to PCIe Bridges are roots of PCIe 804 * Root Ports and PCI/PCI-X to PCIe Bridges are roots of PCIe
diff --git a/drivers/pci/quirks.c b/drivers/pci/quirks.c
index f754453fe754..673683660b5c 100644
--- a/drivers/pci/quirks.c
+++ b/drivers/pci/quirks.c
@@ -2174,6 +2174,7 @@ DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005d, quirk_blacklist_vpd);
2174DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005f, quirk_blacklist_vpd); 2174DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_LSI_LOGIC, 0x005f, quirk_blacklist_vpd);
2175DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, PCI_ANY_ID, 2175DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_ATTANSIC, PCI_ANY_ID,
2176 quirk_blacklist_vpd); 2176 quirk_blacklist_vpd);
2177DECLARE_PCI_FIXUP_FINAL(PCI_VENDOR_ID_QLOGIC, 0x2261, quirk_blacklist_vpd);
2177 2178
2178/* 2179/*
2179 * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the 2180 * For Broadcom 5706, 5708, 5709 rev. A nics, any read beyond the
diff --git a/include/linux/mod_devicetable.h b/include/linux/mod_devicetable.h
index 8850fcaf50db..566fda587fcf 100644
--- a/include/linux/mod_devicetable.h
+++ b/include/linux/mod_devicetable.h
@@ -428,6 +428,16 @@ struct i2c_device_id {
428 kernel_ulong_t driver_data; /* Data private to the driver */ 428 kernel_ulong_t driver_data; /* Data private to the driver */
429}; 429};
430 430
431/* pci_epf */
432
433#define PCI_EPF_NAME_SIZE 20
434#define PCI_EPF_MODULE_PREFIX "pci_epf:"
435
436struct pci_epf_device_id {
437 char name[PCI_EPF_NAME_SIZE];
438 kernel_ulong_t driver_data;
439};
440
431/* spi */ 441/* spi */
432 442
433#define SPI_NAME_SIZE 32 443#define SPI_NAME_SIZE 32
diff --git a/include/linux/pci-ep-cfs.h b/include/linux/pci-ep-cfs.h
new file mode 100644
index 000000000000..263b89ea5705
--- /dev/null
+++ b/include/linux/pci-ep-cfs.h
@@ -0,0 +1,41 @@
1/**
2 * PCI Endpoint ConfigFS header file
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 */
11
12#ifndef __LINUX_PCI_EP_CFS_H
13#define __LINUX_PCI_EP_CFS_H
14
15#include <linux/configfs.h>
16
17#ifdef CONFIG_PCI_ENDPOINT_CONFIGFS
18struct config_group *pci_ep_cfs_add_epc_group(const char *name);
19void pci_ep_cfs_remove_epc_group(struct config_group *group);
20struct config_group *pci_ep_cfs_add_epf_group(const char *name);
21void pci_ep_cfs_remove_epf_group(struct config_group *group);
22#else
23static inline struct config_group *pci_ep_cfs_add_epc_group(const char *name)
24{
25 return 0;
26}
27
28static inline void pci_ep_cfs_remove_epc_group(struct config_group *group)
29{
30}
31
32static inline struct config_group *pci_ep_cfs_add_epf_group(const char *name)
33{
34 return 0;
35}
36
37static inline void pci_ep_cfs_remove_epf_group(struct config_group *group)
38{
39}
40#endif
41#endif /* __LINUX_PCI_EP_CFS_H */
diff --git a/include/linux/pci-epc.h b/include/linux/pci-epc.h
new file mode 100644
index 000000000000..af5edbf3eea3
--- /dev/null
+++ b/include/linux/pci-epc.h
@@ -0,0 +1,144 @@
1/**
2 * PCI Endpoint *Controller* (EPC) header file
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 */
11
12#ifndef __LINUX_PCI_EPC_H
13#define __LINUX_PCI_EPC_H
14
15#include <linux/pci-epf.h>
16
17struct pci_epc;
18
19enum pci_epc_irq_type {
20 PCI_EPC_IRQ_UNKNOWN,
21 PCI_EPC_IRQ_LEGACY,
22 PCI_EPC_IRQ_MSI,
23};
24
25/**
26 * struct pci_epc_ops - set of function pointers for performing EPC operations
27 * @write_header: ops to populate configuration space header
28 * @set_bar: ops to configure the BAR
29 * @clear_bar: ops to reset the BAR
30 * @map_addr: ops to map CPU address to PCI address
31 * @unmap_addr: ops to unmap CPU address and PCI address
32 * @set_msi: ops to set the requested number of MSI interrupts in the MSI
33 * capability register
34 * @get_msi: ops to get the number of MSI interrupts allocated by the RC from
35 * the MSI capability register
36 * @raise_irq: ops to raise a legacy or MSI interrupt
37 * @start: ops to start the PCI link
38 * @stop: ops to stop the PCI link
39 * @owner: the module owner containing the ops
40 */
41struct pci_epc_ops {
42 int (*write_header)(struct pci_epc *pci_epc,
43 struct pci_epf_header *hdr);
44 int (*set_bar)(struct pci_epc *epc, enum pci_barno bar,
45 dma_addr_t bar_phys, size_t size, int flags);
46 void (*clear_bar)(struct pci_epc *epc, enum pci_barno bar);
47 int (*map_addr)(struct pci_epc *epc, phys_addr_t addr,
48 u64 pci_addr, size_t size);
49 void (*unmap_addr)(struct pci_epc *epc, phys_addr_t addr);
50 int (*set_msi)(struct pci_epc *epc, u8 interrupts);
51 int (*get_msi)(struct pci_epc *epc);
52 int (*raise_irq)(struct pci_epc *pci_epc,
53 enum pci_epc_irq_type type, u8 interrupt_num);
54 int (*start)(struct pci_epc *epc);
55 void (*stop)(struct pci_epc *epc);
56 struct module *owner;
57};
58
59/**
60 * struct pci_epc_mem - address space of the endpoint controller
61 * @phys_base: physical base address of the PCI address space
62 * @size: the size of the PCI address space
63 * @bitmap: bitmap to manage the PCI address space
64 * @pages: number of bits representing the address region
65 */
66struct pci_epc_mem {
67 phys_addr_t phys_base;
68 size_t size;
69 unsigned long *bitmap;
70 int pages;
71};
72
73/**
74 * struct pci_epc - represents the PCI EPC device
75 * @dev: PCI EPC device
76 * @pci_epf: list of endpoint functions present in this EPC device
77 * @ops: function pointers for performing endpoint operations
78 * @mem: address space of the endpoint controller
79 * @max_functions: max number of functions that can be configured in this EPC
80 * @group: configfs group representing the PCI EPC device
81 * @lock: spinlock to protect pci_epc ops
82 */
83struct pci_epc {
84 struct device dev;
85 struct list_head pci_epf;
86 const struct pci_epc_ops *ops;
87 struct pci_epc_mem *mem;
88 u8 max_functions;
89 struct config_group *group;
90 /* spinlock to protect against concurrent access of EP controller */
91 spinlock_t lock;
92};
93
94#define to_pci_epc(device) container_of((device), struct pci_epc, dev)
95
96#define pci_epc_create(dev, ops) \
97 __pci_epc_create((dev), (ops), THIS_MODULE)
98#define devm_pci_epc_create(dev, ops) \
99 __devm_pci_epc_create((dev), (ops), THIS_MODULE)
100
101static inline void epc_set_drvdata(struct pci_epc *epc, void *data)
102{
103 dev_set_drvdata(&epc->dev, data);
104}
105
106static inline void *epc_get_drvdata(struct pci_epc *epc)
107{
108 return dev_get_drvdata(&epc->dev);
109}
110
111struct pci_epc *
112__devm_pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
113 struct module *owner);
114struct pci_epc *
115__pci_epc_create(struct device *dev, const struct pci_epc_ops *ops,
116 struct module *owner);
117void devm_pci_epc_destroy(struct device *dev, struct pci_epc *epc);
118void pci_epc_destroy(struct pci_epc *epc);
119int pci_epc_add_epf(struct pci_epc *epc, struct pci_epf *epf);
120void pci_epc_linkup(struct pci_epc *epc);
121void pci_epc_remove_epf(struct pci_epc *epc, struct pci_epf *epf);
122int pci_epc_write_header(struct pci_epc *epc, struct pci_epf_header *hdr);
123int pci_epc_set_bar(struct pci_epc *epc, enum pci_barno bar,
124 dma_addr_t bar_phys, size_t size, int flags);
125void pci_epc_clear_bar(struct pci_epc *epc, int bar);
126int pci_epc_map_addr(struct pci_epc *epc, phys_addr_t phys_addr,
127 u64 pci_addr, size_t size);
128void pci_epc_unmap_addr(struct pci_epc *epc, phys_addr_t phys_addr);
129int pci_epc_set_msi(struct pci_epc *epc, u8 interrupts);
130int pci_epc_get_msi(struct pci_epc *epc);
131int pci_epc_raise_irq(struct pci_epc *epc, enum pci_epc_irq_type type,
132 u8 interrupt_num);
133int pci_epc_start(struct pci_epc *epc);
134void pci_epc_stop(struct pci_epc *epc);
135struct pci_epc *pci_epc_get(const char *epc_name);
136void pci_epc_put(struct pci_epc *epc);
137
138int pci_epc_mem_init(struct pci_epc *epc, phys_addr_t phys_addr, size_t size);
139void pci_epc_mem_exit(struct pci_epc *epc);
140void __iomem *pci_epc_mem_alloc_addr(struct pci_epc *epc,
141 phys_addr_t *phys_addr, size_t size);
142void pci_epc_mem_free_addr(struct pci_epc *epc, phys_addr_t phys_addr,
143 void __iomem *virt_addr, size_t size);
144#endif /* __LINUX_PCI_EPC_H */
diff --git a/include/linux/pci-epf.h b/include/linux/pci-epf.h
new file mode 100644
index 000000000000..0d529cb90143
--- /dev/null
+++ b/include/linux/pci-epf.h
@@ -0,0 +1,162 @@
1/**
2 * PCI Endpoint *Function* (EPF) header file
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 */
11
12#ifndef __LINUX_PCI_EPF_H
13#define __LINUX_PCI_EPF_H
14
15#include <linux/device.h>
16#include <linux/mod_devicetable.h>
17
18struct pci_epf;
19
20enum pci_interrupt_pin {
21 PCI_INTERRUPT_UNKNOWN,
22 PCI_INTERRUPT_INTA,
23 PCI_INTERRUPT_INTB,
24 PCI_INTERRUPT_INTC,
25 PCI_INTERRUPT_INTD,
26};
27
28enum pci_barno {
29 BAR_0,
30 BAR_1,
31 BAR_2,
32 BAR_3,
33 BAR_4,
34 BAR_5,
35};
36
37/**
38 * struct pci_epf_header - represents standard configuration header
39 * @vendorid: identifies device manufacturer
40 * @deviceid: identifies a particular device
41 * @revid: specifies a device-specific revision identifier
42 * @progif_code: identifies a specific register-level programming interface
43 * @subclass_code: identifies more specifically the function of the device
44 * @baseclass_code: broadly classifies the type of function the device performs
45 * @cache_line_size: specifies the system cacheline size in units of DWORDs
46 * @subsys_vendor_id: vendor of the add-in card or subsystem
47 * @subsys_id: id specific to vendor
48 * @interrupt_pin: interrupt pin the device (or device function) uses
49 */
50struct pci_epf_header {
51 u16 vendorid;
52 u16 deviceid;
53 u8 revid;
54 u8 progif_code;
55 u8 subclass_code;
56 u8 baseclass_code;
57 u8 cache_line_size;
58 u16 subsys_vendor_id;
59 u16 subsys_id;
60 enum pci_interrupt_pin interrupt_pin;
61};
62
63/**
64 * struct pci_epf_ops - set of function pointers for performing EPF operations
65 * @bind: ops to perform when a EPC device has been bound to EPF device
66 * @unbind: ops to perform when a binding has been lost between a EPC device
67 * and EPF device
68 * @linkup: ops to perform when the EPC device has established a connection with
69 * a host system
70 */
71struct pci_epf_ops {
72 int (*bind)(struct pci_epf *epf);
73 void (*unbind)(struct pci_epf *epf);
74 void (*linkup)(struct pci_epf *epf);
75};
76
77/**
78 * struct pci_epf_driver - represents the PCI EPF driver
79 * @probe: ops to perform when a new EPF device has been bound to the EPF driver
80 * @remove: ops to perform when the binding between the EPF device and EPF
81 * driver is broken
82 * @driver: PCI EPF driver
83 * @ops: set of function pointers for performing EPF operations
84 * @owner: the owner of the module that registers the PCI EPF driver
85 * @group: configfs group corresponding to the PCI EPF driver
86 * @id_table: identifies EPF devices for probing
87 */
88struct pci_epf_driver {
89 int (*probe)(struct pci_epf *epf);
90 int (*remove)(struct pci_epf *epf);
91
92 struct device_driver driver;
93 struct pci_epf_ops *ops;
94 struct module *owner;
95 struct config_group *group;
96 const struct pci_epf_device_id *id_table;
97};
98
99#define to_pci_epf_driver(drv) (container_of((drv), struct pci_epf_driver, \
100 driver))
101
102/**
103 * struct pci_epf_bar - represents the BAR of EPF device
104 * @phys_addr: physical address that should be mapped to the BAR
105 * @size: the size of the address space present in BAR
106 */
107struct pci_epf_bar {
108 dma_addr_t phys_addr;
109 size_t size;
110};
111
112/**
113 * struct pci_epf - represents the PCI EPF device
114 * @dev: the PCI EPF device
115 * @name: the name of the PCI EPF device
116 * @header: represents standard configuration header
117 * @bar: represents the BAR of EPF device
118 * @msi_interrupts: number of MSI interrupts required by this function
119 * @func_no: unique function number within this endpoint device
120 * @epc: the EPC device to which this EPF device is bound
121 * @driver: the EPF driver to which this EPF device is bound
122 * @list: to add pci_epf as a list of PCI endpoint functions to pci_epc
123 */
124struct pci_epf {
125 struct device dev;
126 const char *name;
127 struct pci_epf_header *header;
128 struct pci_epf_bar bar[6];
129 u8 msi_interrupts;
130 u8 func_no;
131
132 struct pci_epc *epc;
133 struct pci_epf_driver *driver;
134 struct list_head list;
135};
136
137#define to_pci_epf(epf_dev) container_of((epf_dev), struct pci_epf, dev)
138
139#define pci_epf_register_driver(driver) \
140 __pci_epf_register_driver((driver), THIS_MODULE)
141
142static inline void epf_set_drvdata(struct pci_epf *epf, void *data)
143{
144 dev_set_drvdata(&epf->dev, data);
145}
146
147static inline void *epf_get_drvdata(struct pci_epf *epf)
148{
149 return dev_get_drvdata(&epf->dev);
150}
151
152struct pci_epf *pci_epf_create(const char *name);
153void pci_epf_destroy(struct pci_epf *epf);
154int __pci_epf_register_driver(struct pci_epf_driver *driver,
155 struct module *owner);
156void pci_epf_unregister_driver(struct pci_epf_driver *driver);
157void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar);
158void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar);
159int pci_epf_bind(struct pci_epf *epf);
160void pci_epf_unbind(struct pci_epf *epf);
161void pci_epf_linkup(struct pci_epf *epf);
162#endif /* __LINUX_PCI_EPF_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index a4f77feecbb0..5f6b71d15393 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -862,6 +862,8 @@
862#define PCI_DEVICE_ID_TI_X620 0xac8d 862#define PCI_DEVICE_ID_TI_X620 0xac8d
863#define PCI_DEVICE_ID_TI_X420 0xac8e 863#define PCI_DEVICE_ID_TI_X420 0xac8e
864#define PCI_DEVICE_ID_TI_XX20_FM 0xac8f 864#define PCI_DEVICE_ID_TI_XX20_FM 0xac8f
865#define PCI_DEVICE_ID_TI_DRA74x 0xb500
866#define PCI_DEVICE_ID_TI_DRA72x 0xb501
865 867
866#define PCI_VENDOR_ID_SONY 0x104d 868#define PCI_VENDOR_ID_SONY 0x104d
867 869
diff --git a/include/uapi/linux/Kbuild b/include/uapi/linux/Kbuild
index dd9820b1c779..baee6db08287 100644
--- a/include/uapi/linux/Kbuild
+++ b/include/uapi/linux/Kbuild
@@ -333,6 +333,7 @@ header-y += parport.h
333header-y += patchkey.h 333header-y += patchkey.h
334header-y += pci.h 334header-y += pci.h
335header-y += pci_regs.h 335header-y += pci_regs.h
336header-y += pcitest.h
336header-y += perf_event.h 337header-y += perf_event.h
337header-y += personality.h 338header-y += personality.h
338header-y += pfkeyv2.h 339header-y += pfkeyv2.h
diff --git a/include/uapi/linux/pcitest.h b/include/uapi/linux/pcitest.h
new file mode 100644
index 000000000000..a6aa10c45ad1
--- /dev/null
+++ b/include/uapi/linux/pcitest.h
@@ -0,0 +1,19 @@
1/**
2 * pcitest.h - PCI test uapi defines
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 */
8
9#ifndef __UAPI_LINUX_PCITEST_H
10#define __UAPI_LINUX_PCITEST_H
11
12#define PCITEST_BAR _IO('P', 0x1)
13#define PCITEST_LEGACY_IRQ _IO('P', 0x2)
14#define PCITEST_MSI _IOW('P', 0x3, int)
15#define PCITEST_WRITE _IOW('P', 0x4, unsigned long)
16#define PCITEST_READ _IOW('P', 0x5, unsigned long)
17#define PCITEST_COPY _IOW('P', 0x6, unsigned long)
18
19#endif /* __UAPI_LINUX_PCITEST_H */
diff --git a/tools/pci/pcitest.c b/tools/pci/pcitest.c
new file mode 100644
index 000000000000..ad54a58d7dda
--- /dev/null
+++ b/tools/pci/pcitest.c
@@ -0,0 +1,186 @@
1/**
2 * Userspace PCI Endpoint Test Module
3 *
4 * Copyright (C) 2017 Texas Instruments
5 * Author: Kishon Vijay Abraham I <kishon@ti.com>
6 *
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 of
9 * the License as published by the Free Software Foundation.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
18 */
19
20#include <errno.h>
21#include <fcntl.h>
22#include <stdbool.h>
23#include <stdio.h>
24#include <stdlib.h>
25#include <sys/ioctl.h>
26#include <time.h>
27#include <unistd.h>
28
29#include <linux/pcitest.h>
30
31#define BILLION 1E9
32
33static char *result[] = { "NOT OKAY", "OKAY" };
34
35struct pci_test {
36 char *device;
37 char barnum;
38 bool legacyirq;
39 unsigned int msinum;
40 bool read;
41 bool write;
42 bool copy;
43 unsigned long size;
44};
45
46static int run_test(struct pci_test *test)
47{
48 long ret;
49 int fd;
50 struct timespec start, end;
51 double time;
52
53 fd = open(test->device, O_RDWR);
54 if (fd < 0) {
55 perror("can't open PCI Endpoint Test device");
56 return fd;
57 }
58
59 if (test->barnum >= 0 && test->barnum <= 5) {
60 ret = ioctl(fd, PCITEST_BAR, test->barnum);
61 fprintf(stdout, "BAR%d:\t\t", test->barnum);
62 if (ret < 0)
63 fprintf(stdout, "TEST FAILED\n");
64 else
65 fprintf(stdout, "%s\n", result[ret]);
66 }
67
68 if (test->legacyirq) {
69 ret = ioctl(fd, PCITEST_LEGACY_IRQ, 0);
70 fprintf(stdout, "LEGACY IRQ:\t");
71 if (ret < 0)
72 fprintf(stdout, "TEST FAILED\n");
73 else
74 fprintf(stdout, "%s\n", result[ret]);
75 }
76
77 if (test->msinum > 0 && test->msinum <= 32) {
78 ret = ioctl(fd, PCITEST_MSI, test->msinum);
79 fprintf(stdout, "MSI%d:\t\t", test->msinum);
80 if (ret < 0)
81 fprintf(stdout, "TEST FAILED\n");
82 else
83 fprintf(stdout, "%s\n", result[ret]);
84 }
85
86 if (test->write) {
87 ret = ioctl(fd, PCITEST_WRITE, test->size);
88 fprintf(stdout, "WRITE (%7ld bytes):\t\t", test->size);
89 if (ret < 0)
90 fprintf(stdout, "TEST FAILED\n");
91 else
92 fprintf(stdout, "%s\n", result[ret]);
93 }
94
95 if (test->read) {
96 ret = ioctl(fd, PCITEST_READ, test->size);
97 fprintf(stdout, "READ (%7ld bytes):\t\t", test->size);
98 if (ret < 0)
99 fprintf(stdout, "TEST FAILED\n");
100 else
101 fprintf(stdout, "%s\n", result[ret]);
102 }
103
104 if (test->copy) {
105 ret = ioctl(fd, PCITEST_COPY, test->size);
106 fprintf(stdout, "COPY (%7ld bytes):\t\t", test->size);
107 if (ret < 0)
108 fprintf(stdout, "TEST FAILED\n");
109 else
110 fprintf(stdout, "%s\n", result[ret]);
111 }
112
113 fflush(stdout);
114}
115
116int main(int argc, char **argv)
117{
118 int c;
119 struct pci_test *test;
120
121 test = calloc(1, sizeof(*test));
122 if (!test) {
123 perror("Fail to allocate memory for pci_test\n");
124 return -ENOMEM;
125 }
126
127 /* since '0' is a valid BAR number, initialize it to -1 */
128 test->barnum = -1;
129
130 /* set default size as 100KB */
131 test->size = 0x19000;
132
133 /* set default endpoint device */
134 test->device = "/dev/pci-endpoint-test.0";
135
136 while ((c = getopt(argc, argv, "D:b:m:lrwcs:")) != EOF)
137 switch (c) {
138 case 'D':
139 test->device = optarg;
140 continue;
141 case 'b':
142 test->barnum = atoi(optarg);
143 if (test->barnum < 0 || test->barnum > 5)
144 goto usage;
145 continue;
146 case 'l':
147 test->legacyirq = true;
148 continue;
149 case 'm':
150 test->msinum = atoi(optarg);
151 if (test->msinum < 1 || test->msinum > 32)
152 goto usage;
153 continue;
154 case 'r':
155 test->read = true;
156 continue;
157 case 'w':
158 test->write = true;
159 continue;
160 case 'c':
161 test->copy = true;
162 continue;
163 case 's':
164 test->size = strtoul(optarg, NULL, 0);
165 continue;
166 case '?':
167 case 'h':
168 default:
169usage:
170 fprintf(stderr,
171 "usage: %s [options]\n"
172 "Options:\n"
173 "\t-D <dev> PCI endpoint test device {default: /dev/pci-endpoint-test.0}\n"
174 "\t-b <bar num> BAR test (bar number between 0..5)\n"
175 "\t-m <msi num> MSI test (msi number between 1..32)\n"
176 "\t-r Read buffer test\n"
177 "\t-w Write buffer test\n"
178 "\t-c Copy buffer test\n"
179 "\t-s <size> Size of buffer {default: 100KB}\n",
180 argv[0]);
181 return -EINVAL;
182 }
183
184 run_test(test);
185 return 0;
186}
diff --git a/tools/pci/pcitest.sh b/tools/pci/pcitest.sh
new file mode 100644
index 000000000000..5442bbea4c22
--- /dev/null
+++ b/tools/pci/pcitest.sh
@@ -0,0 +1,56 @@
1#!/bin/sh
2
3echo "BAR tests"
4echo
5
6bar=0
7
8while [ $bar -lt 6 ]
9do
10 pcitest -b $bar
11 bar=`expr $bar + 1`
12done
13echo
14
15echo "Interrupt tests"
16echo
17
18pcitest -l
19msi=1
20
21while [ $msi -lt 33 ]
22do
23 pcitest -m $msi
24 msi=`expr $msi + 1`
25done
26echo
27
28echo "Read Tests"
29echo
30
31pcitest -r -s 1
32pcitest -r -s 1024
33pcitest -r -s 1025
34pcitest -r -s 1024000
35pcitest -r -s 1024001
36echo
37
38echo "Write Tests"
39echo
40
41pcitest -w -s 1
42pcitest -w -s 1024
43pcitest -w -s 1025
44pcitest -w -s 1024000
45pcitest -w -s 1024001
46echo
47
48echo "Copy Tests"
49echo
50
51pcitest -c -s 1
52pcitest -c -s 1024
53pcitest -c -s 1025
54pcitest -c -s 1024000
55pcitest -c -s 1024001
56echo