Commit | Line | Data |
---|---|---|
8cfab3cf | 1 | /* SPDX-License-Identifier: GPL-2.0 */ |
4b1ced84 | 2 | /* |
96291d56 | 3 | * Synopsys DesignWare PCIe host controller driver |
4b1ced84 JH |
4 | * |
5 | * Copyright (C) 2013 Samsung Electronics Co., Ltd. | |
7ecd4a81 | 6 | * https://www.samsung.com |
4b1ced84 JH |
7 | * |
8 | * Author: Jingoo Han <jg1.han@samsung.com> | |
4b1ced84 JH |
9 | */ |
10 | ||
18edf451 SJ |
11 | #ifndef _PCIE_DESIGNWARE_H |
12 | #define _PCIE_DESIGNWARE_H | |
13 | ||
a991f748 | 14 | #include <linux/bitfield.h> |
7f9e982d | 15 | #include <linux/bitops.h> |
ef69f852 | 16 | #include <linux/clk.h> |
111111a7 | 17 | #include <linux/dma-mapping.h> |
939fbcd5 | 18 | #include <linux/dma/edma.h> |
ef69f852 | 19 | #include <linux/gpio/consumer.h> |
feb85d9b KVA |
20 | #include <linux/irq.h> |
21 | #include <linux/msi.h> | |
22 | #include <linux/pci.h> | |
ef69f852 | 23 | #include <linux/reset.h> |
feb85d9b | 24 | |
f8aed6ec KVA |
25 | #include <linux/pci-epc.h> |
26 | #include <linux/pci-epf.h> | |
27 | ||
afe1c6d5 SS |
28 | /* DWC PCIe IP-core versions (native support since v4.70a) */ |
29 | #define DW_PCIE_VER_365A 0x3336352a | |
30 | #define DW_PCIE_VER_460A 0x3436302a | |
31 | #define DW_PCIE_VER_470A 0x3437302a | |
32 | #define DW_PCIE_VER_480A 0x3438302a | |
33 | #define DW_PCIE_VER_490A 0x3439302a | |
34 | #define DW_PCIE_VER_520A 0x3532302a | |
939fbcd5 | 35 | #define DW_PCIE_VER_540A 0x3534302a |
afe1c6d5 | 36 | |
0b0a780d SS |
37 | #define __dw_pcie_ver_cmp(_pci, _ver, _op) \ |
38 | ((_pci)->version _op DW_PCIE_VER_ ## _ver) | |
39 | ||
40 | #define dw_pcie_ver_is(_pci, _ver) __dw_pcie_ver_cmp(_pci, _ver, ==) | |
41 | ||
42 | #define dw_pcie_ver_is_ge(_pci, _ver) __dw_pcie_ver_cmp(_pci, _ver, >=) | |
43 | ||
44 | #define dw_pcie_ver_type_is(_pci, _ver, _type) \ | |
45 | (__dw_pcie_ver_cmp(_pci, _ver, ==) && \ | |
46 | __dw_pcie_ver_cmp(_pci, TYPE_ ## _type, ==)) | |
47 | ||
48 | #define dw_pcie_ver_type_is_ge(_pci, _ver, _type) \ | |
49 | (__dw_pcie_ver_cmp(_pci, _ver, ==) && \ | |
50 | __dw_pcie_ver_cmp(_pci, TYPE_ ## _type, >=)) | |
51 | ||
7f9e982d | 52 | /* DWC PCIe controller capabilities */ |
ef69f852 | 53 | #define DW_PCIE_CAP_REQ_RES 0 |
7f9e982d | 54 | #define DW_PCIE_CAP_IATU_UNROLL 1 |
ef8c5887 | 55 | #define DW_PCIE_CAP_CDM_CHECK 2 |
7f9e982d SS |
56 | |
57 | #define dw_pcie_cap_is(_pci, _cap) \ | |
58 | test_bit(DW_PCIE_CAP_ ## _cap, &(_pci)->caps) | |
59 | ||
60 | #define dw_pcie_cap_set(_pci, _cap) \ | |
61 | set_bit(DW_PCIE_CAP_ ## _cap, &(_pci)->caps) | |
62 | ||
b90dc392 KVA |
63 | /* Parameters for the waiting for link up routine */ |
64 | #define LINK_WAIT_MAX_RETRIES 10 | |
65 | #define LINK_WAIT_USLEEP_MIN 90000 | |
66 | #define LINK_WAIT_USLEEP_MAX 100000 | |
67 | ||
68 | /* Parameters for the waiting for iATU enabled routine */ | |
69 | #define LINK_WAIT_MAX_IATU_RETRIES 5 | |
9024143e | 70 | #define LINK_WAIT_IATU 9 |
b90dc392 KVA |
71 | |
72 | /* Synopsys-specific PCIe configuration registers */ | |
ed22aaae DK |
73 | #define PCIE_PORT_AFR 0x70C |
74 | #define PORT_AFR_N_FTS_MASK GENMASK(15, 8) | |
84667a41 | 75 | #define PORT_AFR_N_FTS(n) FIELD_PREP(PORT_AFR_N_FTS_MASK, n) |
ed22aaae | 76 | #define PORT_AFR_CC_N_FTS_MASK GENMASK(23, 16) |
aeaa0bfe | 77 | #define PORT_AFR_CC_N_FTS(n) FIELD_PREP(PORT_AFR_CC_N_FTS_MASK, n) |
84667a41 RH |
78 | #define PORT_AFR_ENTER_ASPM BIT(30) |
79 | #define PORT_AFR_L0S_ENTRANCE_LAT_SHIFT 24 | |
80 | #define PORT_AFR_L0S_ENTRANCE_LAT_MASK GENMASK(26, 24) | |
81 | #define PORT_AFR_L1_ENTRANCE_LAT_SHIFT 27 | |
82 | #define PORT_AFR_L1_ENTRANCE_LAT_MASK GENMASK(29, 27) | |
ed22aaae | 83 | |
b90dc392 | 84 | #define PCIE_PORT_LINK_CONTROL 0x710 |
ed22aaae | 85 | #define PORT_LINK_DLL_LINK_EN BIT(5) |
cff92444 | 86 | #define PORT_LINK_FAST_LINK_MODE BIT(7) |
a991f748 AS |
87 | #define PORT_LINK_MODE_MASK GENMASK(21, 16) |
88 | #define PORT_LINK_MODE(n) FIELD_PREP(PORT_LINK_MODE_MASK, n) | |
89 | #define PORT_LINK_MODE_1_LANES PORT_LINK_MODE(0x1) | |
90 | #define PORT_LINK_MODE_2_LANES PORT_LINK_MODE(0x3) | |
91 | #define PORT_LINK_MODE_4_LANES PORT_LINK_MODE(0x7) | |
92 | #define PORT_LINK_MODE_8_LANES PORT_LINK_MODE(0xf) | |
b90dc392 | 93 | |
23fe5bd4 KVA |
94 | #define PCIE_PORT_DEBUG0 0x728 |
95 | #define PORT_LOGIC_LTSSM_STATE_MASK 0x1f | |
96 | #define PORT_LOGIC_LTSSM_STATE_L0 0x11 | |
60ef4b07 AS |
97 | #define PCIE_PORT_DEBUG1 0x72C |
98 | #define PCIE_PORT_DEBUG1_LINK_UP BIT(4) | |
99 | #define PCIE_PORT_DEBUG1_LINK_IN_TRAINING BIT(29) | |
23fe5bd4 | 100 | |
b90dc392 | 101 | #define PCIE_LINK_WIDTH_SPEED_CONTROL 0x80C |
ed22aaae | 102 | #define PORT_LOGIC_N_FTS_MASK GENMASK(7, 0) |
0e11faa4 | 103 | #define PORT_LOGIC_SPEED_CHANGE BIT(17) |
a991f748 AS |
104 | #define PORT_LOGIC_LINK_WIDTH_MASK GENMASK(12, 8) |
105 | #define PORT_LOGIC_LINK_WIDTH(n) FIELD_PREP(PORT_LOGIC_LINK_WIDTH_MASK, n) | |
106 | #define PORT_LOGIC_LINK_WIDTH_1_LANES PORT_LOGIC_LINK_WIDTH(0x1) | |
107 | #define PORT_LOGIC_LINK_WIDTH_2_LANES PORT_LOGIC_LINK_WIDTH(0x2) | |
108 | #define PORT_LOGIC_LINK_WIDTH_4_LANES PORT_LOGIC_LINK_WIDTH(0x4) | |
109 | #define PORT_LOGIC_LINK_WIDTH_8_LANES PORT_LOGIC_LINK_WIDTH(0x8) | |
b90dc392 KVA |
110 | |
111 | #define PCIE_MSI_ADDR_LO 0x820 | |
112 | #define PCIE_MSI_ADDR_HI 0x824 | |
113 | #define PCIE_MSI_INTR0_ENABLE 0x828 | |
114 | #define PCIE_MSI_INTR0_MASK 0x82C | |
115 | #define PCIE_MSI_INTR0_STATUS 0x830 | |
116 | ||
996ab868 BS |
117 | #define GEN3_RELATED_OFF 0x890 |
118 | #define GEN3_RELATED_OFF_GEN3_ZRXDC_NONCOMPL BIT(0) | |
0cf7c2ef | 119 | #define GEN3_RELATED_OFF_RXEQ_RGRDLESS_RXTS BIT(13) |
996ab868 BS |
120 | #define GEN3_RELATED_OFF_GEN3_EQ_DISABLE BIT(16) |
121 | #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_SHIFT 24 | |
122 | #define GEN3_RELATED_OFF_RATE_SHADOW_SEL_MASK GENMASK(25, 24) | |
123 | ||
ed22aaae DK |
124 | #define PCIE_PORT_MULTI_LANE_CTRL 0x8C0 |
125 | #define PORT_MLTI_UPCFG_SUPPORT BIT(7) | |
126 | ||
13e9d390 SS |
127 | #define PCIE_VERSION_NUMBER 0x8F8 |
128 | #define PCIE_VERSION_TYPE 0x8FC | |
129 | ||
5a163f59 SS |
130 | /* |
131 | * iATU inbound and outbound windows CSRs. Before the IP-core v4.80a each | |
132 | * iATU region CSRs had been indirectly accessible by means of the dedicated | |
133 | * viewport selector. The iATU/eDMA CSRs space was re-designed in DWC PCIe | |
134 | * v4.80a in a way so the viewport was unrolled into the directly accessible | |
135 | * iATU/eDMA CSRs space. | |
136 | */ | |
b90dc392 | 137 | #define PCIE_ATU_VIEWPORT 0x900 |
38fe2723 SS |
138 | #define PCIE_ATU_REGION_DIR_IB BIT(31) |
139 | #define PCIE_ATU_REGION_DIR_OB 0 | |
5a163f59 SS |
140 | #define PCIE_ATU_VIEWPORT_BASE 0x904 |
141 | #define PCIE_ATU_UNROLL_BASE(dir, index) \ | |
142 | (((index) << 9) | ((dir == PCIE_ATU_REGION_DIR_IB) ? BIT(8) : 0)) | |
143 | #define PCIE_ATU_VIEWPORT_SIZE 0x2C | |
144 | #define PCIE_ATU_REGION_CTRL1 0x000 | |
74081de4 | 145 | #define PCIE_ATU_INCREASE_REGION_SIZE BIT(13) |
44ddb77b AS |
146 | #define PCIE_ATU_TYPE_MEM 0x0 |
147 | #define PCIE_ATU_TYPE_IO 0x2 | |
148 | #define PCIE_ATU_TYPE_CFG0 0x4 | |
149 | #define PCIE_ATU_TYPE_CFG1 0x5 | |
6104033b | 150 | #define PCIE_ATU_TD BIT(8) |
24ede430 | 151 | #define PCIE_ATU_FUNC_NUM(pf) ((pf) << 20) |
5a163f59 | 152 | #define PCIE_ATU_REGION_CTRL2 0x004 |
0e11faa4 AS |
153 | #define PCIE_ATU_ENABLE BIT(31) |
154 | #define PCIE_ATU_BAR_MODE_ENABLE BIT(30) | |
24ede430 | 155 | #define PCIE_ATU_FUNC_NUM_MATCH_EN BIT(19) |
5a163f59 SS |
156 | #define PCIE_ATU_LOWER_BASE 0x008 |
157 | #define PCIE_ATU_UPPER_BASE 0x00C | |
158 | #define PCIE_ATU_LIMIT 0x010 | |
159 | #define PCIE_ATU_LOWER_TARGET 0x014 | |
a991f748 AS |
160 | #define PCIE_ATU_BUS(x) FIELD_PREP(GENMASK(31, 24), x) |
161 | #define PCIE_ATU_DEV(x) FIELD_PREP(GENMASK(23, 19), x) | |
162 | #define PCIE_ATU_FUNC(x) FIELD_PREP(GENMASK(18, 16), x) | |
5a163f59 SS |
163 | #define PCIE_ATU_UPPER_TARGET 0x018 |
164 | #define PCIE_ATU_UPPER_LIMIT 0x020 | |
b90dc392 | 165 | |
e44abfed | 166 | #define PCIE_MISC_CONTROL_1_OFF 0x8BC |
0e11faa4 | 167 | #define PCIE_DBI_RO_WR_EN BIT(0) |
e44abfed | 168 | |
2f7f7001 XB |
169 | #define PCIE_MSIX_DOORBELL 0x948 |
170 | #define PCIE_MSIX_DOORBELL_PF_SHIFT 24 | |
171 | ||
939fbcd5 SS |
172 | /* |
173 | * eDMA CSRs. DW PCIe IP-core v4.70a and older had the eDMA registers accessible | |
174 | * over the Port Logic registers space. Afterwards the unrolled mapping was | |
175 | * introduced so eDMA and iATU could be accessed via a dedicated registers | |
176 | * space. | |
177 | */ | |
178 | #define PCIE_DMA_VIEWPORT_BASE 0x970 | |
179 | #define PCIE_DMA_UNROLL_BASE 0x80000 | |
180 | #define PCIE_DMA_CTRL 0x008 | |
181 | #define PCIE_DMA_NUM_WR_CHAN GENMASK(3, 0) | |
182 | #define PCIE_DMA_NUM_RD_CHAN GENMASK(19, 16) | |
183 | ||
07f123de VS |
184 | #define PCIE_PL_CHK_REG_CONTROL_STATUS 0xB20 |
185 | #define PCIE_PL_CHK_REG_CHK_REG_START BIT(0) | |
186 | #define PCIE_PL_CHK_REG_CHK_REG_CONTINUOUS BIT(1) | |
187 | #define PCIE_PL_CHK_REG_CHK_REG_COMPARISON_ERROR BIT(16) | |
188 | #define PCIE_PL_CHK_REG_CHK_REG_LOGIC_ERROR BIT(17) | |
189 | #define PCIE_PL_CHK_REG_CHK_REG_COMPLETE BIT(18) | |
190 | ||
191 | #define PCIE_PL_CHK_REG_ERR_ADDR 0xB28 | |
192 | ||
b90dc392 KVA |
193 | /* |
194 | * iATU Unroll-specific register definitions | |
195 | * From 4.80 core version the address translation will be made by unroll | |
196 | */ | |
197 | #define PCIE_ATU_UNR_REGION_CTRL1 0x00 | |
198 | #define PCIE_ATU_UNR_REGION_CTRL2 0x04 | |
199 | #define PCIE_ATU_UNR_LOWER_BASE 0x08 | |
200 | #define PCIE_ATU_UNR_UPPER_BASE 0x0C | |
668b4490 | 201 | #define PCIE_ATU_UNR_LOWER_LIMIT 0x10 |
b90dc392 KVA |
202 | #define PCIE_ATU_UNR_LOWER_TARGET 0x14 |
203 | #define PCIE_ATU_UNR_UPPER_TARGET 0x18 | |
668b4490 | 204 | #define PCIE_ATU_UNR_UPPER_LIMIT 0x20 |
b90dc392 | 205 | |
997b99e3 VS |
206 | /* |
207 | * RAS-DES register definitions | |
208 | */ | |
209 | #define PCIE_RAS_DES_EVENT_COUNTER_CONTROL 0x8 | |
210 | #define EVENT_COUNTER_ALL_CLEAR 0x3 | |
211 | #define EVENT_COUNTER_ENABLE_ALL 0x7 | |
212 | #define EVENT_COUNTER_ENABLE_SHIFT 2 | |
213 | #define EVENT_COUNTER_EVENT_SEL_MASK GENMASK(7, 0) | |
214 | #define EVENT_COUNTER_EVENT_SEL_SHIFT 16 | |
215 | #define EVENT_COUNTER_EVENT_Tx_L0S 0x2 | |
216 | #define EVENT_COUNTER_EVENT_Rx_L0S 0x3 | |
217 | #define EVENT_COUNTER_EVENT_L1 0x5 | |
218 | #define EVENT_COUNTER_EVENT_L1_1 0x7 | |
219 | #define EVENT_COUNTER_EVENT_L1_2 0x8 | |
220 | #define EVENT_COUNTER_GROUP_SEL_SHIFT 24 | |
221 | #define EVENT_COUNTER_GROUP_5 0x5 | |
222 | ||
223 | #define PCIE_RAS_DES_EVENT_COUNTER_DATA 0xc | |
224 | ||
6d6b05e3 SW |
225 | /* |
226 | * The default address offset between dbi_base and atu_base. Root controller | |
227 | * drivers are not required to initialize atu_base if the offset matches this | |
228 | * default; the driver core automatically derives atu_base from dbi_base using | |
229 | * this offset, if atu_base not set. | |
230 | */ | |
231 | #define DEFAULT_DBI_ATU_OFFSET (0x3 << 20) | |
939fbcd5 | 232 | #define DEFAULT_DBI_DMA_OFFSET PCIE_DMA_UNROLL_BASE |
6d6b05e3 | 233 | |
1f319cb0 GP |
234 | #define MAX_MSI_IRQS 256 |
235 | #define MAX_MSI_IRQS_PER_CTRL 32 | |
236 | #define MAX_MSI_CTRLS (MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL) | |
76cbf066 | 237 | #define MSI_REG_CTRL_BLOCK_SIZE 12 |
7c5925af | 238 | #define MSI_DEF_NUM_VECTORS 32 |
f342d940 | 239 | |
ad4a5bec NC |
240 | /* Maximum number of inbound/outbound iATUs */ |
241 | #define MAX_IATU_IN 256 | |
242 | #define MAX_IATU_OUT 256 | |
243 | ||
939fbcd5 SS |
244 | /* Default eDMA LLP memory size */ |
245 | #define DMA_LLP_MEM_SIZE PAGE_SIZE | |
246 | ||
442ec4c0 | 247 | struct dw_pcie; |
60b3c27f | 248 | struct dw_pcie_rp; |
f8aed6ec KVA |
249 | struct dw_pcie_ep; |
250 | ||
608793e2 KVA |
251 | enum dw_pcie_device_mode { |
252 | DW_PCIE_UNKNOWN_TYPE, | |
253 | DW_PCIE_EP_TYPE, | |
254 | DW_PCIE_LEG_EP_TYPE, | |
255 | DW_PCIE_RC_TYPE, | |
256 | }; | |
257 | ||
ef69f852 SS |
258 | enum dw_pcie_app_clk { |
259 | DW_PCIE_DBI_CLK, | |
260 | DW_PCIE_MSTR_CLK, | |
261 | DW_PCIE_SLV_CLK, | |
262 | DW_PCIE_NUM_APP_CLKS | |
263 | }; | |
264 | ||
265 | enum dw_pcie_core_clk { | |
266 | DW_PCIE_PIPE_CLK, | |
267 | DW_PCIE_CORE_CLK, | |
268 | DW_PCIE_AUX_CLK, | |
269 | DW_PCIE_REF_CLK, | |
270 | DW_PCIE_NUM_CORE_CLKS | |
271 | }; | |
272 | ||
273 | enum dw_pcie_app_rst { | |
274 | DW_PCIE_DBI_RST, | |
275 | DW_PCIE_MSTR_RST, | |
276 | DW_PCIE_SLV_RST, | |
277 | DW_PCIE_NUM_APP_RSTS | |
278 | }; | |
279 | ||
280 | enum dw_pcie_core_rst { | |
281 | DW_PCIE_NON_STICKY_RST, | |
282 | DW_PCIE_STICKY_RST, | |
283 | DW_PCIE_CORE_RST, | |
284 | DW_PCIE_PIPE_RST, | |
285 | DW_PCIE_PHY_RST, | |
286 | DW_PCIE_HOT_RST, | |
287 | DW_PCIE_PWR_RST, | |
288 | DW_PCIE_NUM_CORE_RSTS | |
289 | }; | |
290 | ||
442ec4c0 | 291 | struct dw_pcie_host_ops { |
60b3c27f | 292 | int (*host_init)(struct dw_pcie_rp *pp); |
c6481d51 | 293 | void (*host_deinit)(struct dw_pcie_rp *pp); |
60b3c27f | 294 | int (*msi_host_init)(struct dw_pcie_rp *pp); |
442ec4c0 KVA |
295 | }; |
296 | ||
60b3c27f | 297 | struct dw_pcie_rp { |
f78f0263 | 298 | bool has_msi_ctrl:1; |
d6bdbcd8 | 299 | bool cfg0_io_shared:1; |
4b1ced84 JH |
300 | u64 cfg0_base; |
301 | void __iomem *va_cfg0_base; | |
adf70fc0 | 302 | u32 cfg0_size; |
0021d22b | 303 | resource_size_t io_base; |
adf70fc0 PA |
304 | phys_addr_t io_bus_addr; |
305 | u32 io_size; | |
4b1ced84 | 306 | int irq; |
4ab2e7c0 | 307 | const struct dw_pcie_host_ops *ops; |
db388348 | 308 | int msi_irq[MAX_MSI_CTRLS]; |
904d0e78 | 309 | struct irq_domain *irq_domain; |
7c5925af | 310 | struct irq_domain *msi_domain; |
111111a7 | 311 | dma_addr_t msi_data; |
9f67437b | 312 | struct irq_chip *msi_irq_chip; |
7c5925af | 313 | u32 num_vectors; |
a348d015 | 314 | u32 irq_mask[MAX_MSI_CTRLS]; |
444ddca5 | 315 | struct pci_host_bridge *bridge; |
7c5925af | 316 | raw_spinlock_t lock; |
f342d940 | 317 | DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS); |
4b1ced84 JH |
318 | }; |
319 | ||
f8aed6ec KVA |
320 | struct dw_pcie_ep_ops { |
321 | void (*ep_init)(struct dw_pcie_ep *ep); | |
16093362 | 322 | int (*raise_irq)(struct dw_pcie_ep *ep, u8 func_no, |
d3c70a98 | 323 | enum pci_epc_irq_type type, u16 interrupt_num); |
fee35cb7 | 324 | const struct pci_epc_features* (*get_features)(struct dw_pcie_ep *ep); |
24ede430 XB |
325 | /* |
326 | * Provide a method to implement the different func config space | |
327 | * access for different platform, if different func have different | |
328 | * offset, return the offset of func. if use write a register way | |
329 | * return a 0, and implement code in callback function of platform | |
330 | * driver. | |
331 | */ | |
332 | unsigned int (*func_conf_select)(struct dw_pcie_ep *ep, u8 func_no); | |
f8aed6ec KVA |
333 | }; |
334 | ||
47a06260 XB |
335 | struct dw_pcie_ep_func { |
336 | struct list_head list; | |
337 | u8 func_no; | |
338 | u8 msi_cap; /* MSI capability offset */ | |
339 | u8 msix_cap; /* MSI-X capability offset */ | |
340 | }; | |
341 | ||
f8aed6ec KVA |
342 | struct dw_pcie_ep { |
343 | struct pci_epc *epc; | |
47a06260 | 344 | struct list_head func_list; |
626961dd | 345 | const struct dw_pcie_ep_ops *ops; |
f8aed6ec KVA |
346 | phys_addr_t phys_base; |
347 | size_t addr_size; | |
a937fe08 | 348 | size_t page_size; |
c9c13ba4 | 349 | u8 bar_to_atu[PCI_STD_NUM_BARS]; |
f8aed6ec | 350 | phys_addr_t *outbound_addr; |
ad4a5bec NC |
351 | unsigned long *ib_window_map; |
352 | unsigned long *ob_window_map; | |
2fd0c9d9 NC |
353 | void __iomem *msi_mem; |
354 | phys_addr_t msi_mem_phys; | |
6f5e193b | 355 | struct pci_epf_bar *epf_bar[PCI_STD_NUM_BARS]; |
f8aed6ec KVA |
356 | }; |
357 | ||
442ec4c0 | 358 | struct dw_pcie_ops { |
b6900aeb | 359 | u64 (*cpu_addr_fixup)(struct dw_pcie *pcie, u64 cpu_addr); |
a509d7d9 KVA |
360 | u32 (*read_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, |
361 | size_t size); | |
362 | void (*write_dbi)(struct dw_pcie *pcie, void __iomem *base, u32 reg, | |
363 | size_t size, u32 val); | |
ddf567e3 KVA |
364 | void (*write_dbi2)(struct dw_pcie *pcie, void __iomem *base, u32 reg, |
365 | size_t size, u32 val); | |
442ec4c0 | 366 | int (*link_up)(struct dw_pcie *pcie); |
f8aed6ec KVA |
367 | int (*start_link)(struct dw_pcie *pcie); |
368 | void (*stop_link)(struct dw_pcie *pcie); | |
4b1ced84 JH |
369 | }; |
370 | ||
442ec4c0 KVA |
371 | struct dw_pcie { |
372 | struct device *dev; | |
373 | void __iomem *dbi_base; | |
f8aed6ec | 374 | void __iomem *dbi_base2; |
6d6b05e3 | 375 | void __iomem *atu_base; |
281f1f99 | 376 | size_t atu_size; |
9ca17af5 RH |
377 | u32 num_ib_windows; |
378 | u32 num_ob_windows; | |
89473aa9 SS |
379 | u32 region_align; |
380 | u64 region_limit; | |
60b3c27f | 381 | struct dw_pcie_rp pp; |
f8aed6ec | 382 | struct dw_pcie_ep ep; |
442ec4c0 | 383 | const struct dw_pcie_ops *ops; |
afe1c6d5 | 384 | u32 version; |
13e9d390 | 385 | u32 type; |
7f9e982d | 386 | unsigned long caps; |
6ffc02d2 | 387 | int num_lanes; |
39bc5006 | 388 | int link_gen; |
aeaa0bfe | 389 | u8 n_fts[2]; |
939fbcd5 | 390 | struct dw_edma_chip edma; |
ef69f852 SS |
391 | struct clk_bulk_data app_clks[DW_PCIE_NUM_APP_CLKS]; |
392 | struct clk_bulk_data core_clks[DW_PCIE_NUM_CORE_CLKS]; | |
393 | struct reset_control_bulk_data app_rsts[DW_PCIE_NUM_APP_RSTS]; | |
394 | struct reset_control_bulk_data core_rsts[DW_PCIE_NUM_CORE_RSTS]; | |
395 | struct gpio_desc *pe_rst; | |
442ec4c0 KVA |
396 | }; |
397 | ||
398 | #define to_dw_pcie_from_pp(port) container_of((port), struct dw_pcie, pp) | |
399 | ||
f8aed6ec KVA |
400 | #define to_dw_pcie_from_ep(endpoint) \ |
401 | container_of((endpoint), struct dw_pcie, ep) | |
402 | ||
ef8c5887 SS |
403 | int dw_pcie_get_resources(struct dw_pcie *pci); |
404 | ||
13e9d390 SS |
405 | void dw_pcie_version_detect(struct dw_pcie *pci); |
406 | ||
7a6854f6 | 407 | u8 dw_pcie_find_capability(struct dw_pcie *pci, u8 cap); |
5b0841fa | 408 | u16 dw_pcie_find_ext_capability(struct dw_pcie *pci, u8 cap); |
7a6854f6 | 409 | |
19ce01cc KVA |
410 | int dw_pcie_read(void __iomem *addr, int size, u32 *val); |
411 | int dw_pcie_write(void __iomem *addr, int size, u32 val); | |
18edf451 | 412 | |
7bc082d7 VS |
413 | u32 dw_pcie_read_dbi(struct dw_pcie *pci, u32 reg, size_t size); |
414 | void dw_pcie_write_dbi(struct dw_pcie *pci, u32 reg, size_t size, u32 val); | |
7bc082d7 | 415 | void dw_pcie_write_dbi2(struct dw_pcie *pci, u32 reg, size_t size, u32 val); |
442ec4c0 | 416 | int dw_pcie_link_up(struct dw_pcie *pci); |
ed22aaae | 417 | void dw_pcie_upconfig_setup(struct dw_pcie *pci); |
442ec4c0 | 418 | int dw_pcie_wait_for_link(struct dw_pcie *pci); |
edf408b9 SS |
419 | int dw_pcie_prog_outbound_atu(struct dw_pcie *pci, int index, int type, |
420 | u64 cpu_addr, u64 pci_addr, u64 size); | |
421 | int dw_pcie_prog_ep_outbound_atu(struct dw_pcie *pci, u8 func_no, int index, | |
422 | int type, u64 cpu_addr, u64 pci_addr, u64 size); | |
8522e17d SS |
423 | int dw_pcie_prog_inbound_atu(struct dw_pcie *pci, int index, int type, |
424 | u64 cpu_addr, u64 pci_addr, u64 size); | |
425 | int dw_pcie_prog_ep_inbound_atu(struct dw_pcie *pci, u8 func_no, int index, | |
426 | int type, u64 cpu_addr, u8 bar); | |
38fe2723 | 427 | void dw_pcie_disable_atu(struct dw_pcie *pci, u32 dir, int index); |
feb85d9b | 428 | void dw_pcie_setup(struct dw_pcie *pci); |
8bcca265 | 429 | void dw_pcie_iatu_detect(struct dw_pcie *pci); |
939fbcd5 SS |
430 | int dw_pcie_edma_detect(struct dw_pcie *pci); |
431 | void dw_pcie_edma_remove(struct dw_pcie *pci); | |
a0560209 | 432 | |
b50b2db2 KVA |
433 | static inline void dw_pcie_writel_dbi(struct dw_pcie *pci, u32 reg, u32 val) |
434 | { | |
7bc082d7 | 435 | dw_pcie_write_dbi(pci, reg, 0x4, val); |
b50b2db2 KVA |
436 | } |
437 | ||
438 | static inline u32 dw_pcie_readl_dbi(struct dw_pcie *pci, u32 reg) | |
439 | { | |
7bc082d7 | 440 | return dw_pcie_read_dbi(pci, reg, 0x4); |
b50b2db2 KVA |
441 | } |
442 | ||
f8aed6ec KVA |
443 | static inline void dw_pcie_writew_dbi(struct dw_pcie *pci, u32 reg, u16 val) |
444 | { | |
7bc082d7 | 445 | dw_pcie_write_dbi(pci, reg, 0x2, val); |
f8aed6ec KVA |
446 | } |
447 | ||
448 | static inline u16 dw_pcie_readw_dbi(struct dw_pcie *pci, u32 reg) | |
449 | { | |
7bc082d7 | 450 | return dw_pcie_read_dbi(pci, reg, 0x2); |
f8aed6ec KVA |
451 | } |
452 | ||
453 | static inline void dw_pcie_writeb_dbi(struct dw_pcie *pci, u32 reg, u8 val) | |
454 | { | |
7bc082d7 | 455 | dw_pcie_write_dbi(pci, reg, 0x1, val); |
f8aed6ec KVA |
456 | } |
457 | ||
458 | static inline u8 dw_pcie_readb_dbi(struct dw_pcie *pci, u32 reg) | |
459 | { | |
7bc082d7 | 460 | return dw_pcie_read_dbi(pci, reg, 0x1); |
f8aed6ec KVA |
461 | } |
462 | ||
463 | static inline void dw_pcie_writel_dbi2(struct dw_pcie *pci, u32 reg, u32 val) | |
464 | { | |
7bc082d7 | 465 | dw_pcie_write_dbi2(pci, reg, 0x4, val); |
f8aed6ec KVA |
466 | } |
467 | ||
e44abfed HZ |
468 | static inline void dw_pcie_dbi_ro_wr_en(struct dw_pcie *pci) |
469 | { | |
470 | u32 reg; | |
471 | u32 val; | |
472 | ||
473 | reg = PCIE_MISC_CONTROL_1_OFF; | |
474 | val = dw_pcie_readl_dbi(pci, reg); | |
475 | val |= PCIE_DBI_RO_WR_EN; | |
476 | dw_pcie_writel_dbi(pci, reg, val); | |
477 | } | |
478 | ||
479 | static inline void dw_pcie_dbi_ro_wr_dis(struct dw_pcie *pci) | |
480 | { | |
481 | u32 reg; | |
482 | u32 val; | |
483 | ||
484 | reg = PCIE_MISC_CONTROL_1_OFF; | |
485 | val = dw_pcie_readl_dbi(pci, reg); | |
486 | val &= ~PCIE_DBI_RO_WR_EN; | |
487 | dw_pcie_writel_dbi(pci, reg, val); | |
488 | } | |
489 | ||
a37beefb SS |
490 | static inline int dw_pcie_start_link(struct dw_pcie *pci) |
491 | { | |
492 | if (pci->ops && pci->ops->start_link) | |
493 | return pci->ops->start_link(pci); | |
494 | ||
495 | return 0; | |
496 | } | |
497 | ||
498 | static inline void dw_pcie_stop_link(struct dw_pcie *pci) | |
499 | { | |
500 | if (pci->ops && pci->ops->stop_link) | |
501 | pci->ops->stop_link(pci); | |
502 | } | |
503 | ||
a0560209 | 504 | #ifdef CONFIG_PCIE_DW_HOST |
60b3c27f | 505 | irqreturn_t dw_handle_msi_irq(struct dw_pcie_rp *pp); |
ce06bf57 | 506 | int dw_pcie_setup_rc(struct dw_pcie_rp *pp); |
60b3c27f SS |
507 | int dw_pcie_host_init(struct dw_pcie_rp *pp); |
508 | void dw_pcie_host_deinit(struct dw_pcie_rp *pp); | |
509 | int dw_pcie_allocate_domains(struct dw_pcie_rp *pp); | |
27e7ed01 RH |
510 | void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, unsigned int devfn, |
511 | int where); | |
a0560209 | 512 | #else |
60b3c27f | 513 | static inline irqreturn_t dw_handle_msi_irq(struct dw_pcie_rp *pp) |
a0560209 KVA |
514 | { |
515 | return IRQ_NONE; | |
516 | } | |
517 | ||
ce06bf57 | 518 | static inline int dw_pcie_setup_rc(struct dw_pcie_rp *pp) |
a0560209 | 519 | { |
ce06bf57 | 520 | return 0; |
a0560209 KVA |
521 | } |
522 | ||
60b3c27f | 523 | static inline int dw_pcie_host_init(struct dw_pcie_rp *pp) |
a0560209 KVA |
524 | { |
525 | return 0; | |
526 | } | |
7c5925af | 527 | |
60b3c27f | 528 | static inline void dw_pcie_host_deinit(struct dw_pcie_rp *pp) |
9d071cad VS |
529 | { |
530 | } | |
531 | ||
60b3c27f | 532 | static inline int dw_pcie_allocate_domains(struct dw_pcie_rp *pp) |
7c5925af GP |
533 | { |
534 | return 0; | |
535 | } | |
27e7ed01 RH |
536 | static inline void __iomem *dw_pcie_own_conf_map_bus(struct pci_bus *bus, |
537 | unsigned int devfn, | |
538 | int where) | |
539 | { | |
540 | return NULL; | |
541 | } | |
a0560209 | 542 | #endif |
f8aed6ec KVA |
543 | |
544 | #ifdef CONFIG_PCIE_DW_EP | |
545 | void dw_pcie_ep_linkup(struct dw_pcie_ep *ep); | |
546 | int dw_pcie_ep_init(struct dw_pcie_ep *ep); | |
e966f739 | 547 | int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep); |
ac37dde7 | 548 | void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep); |
f8aed6ec | 549 | void dw_pcie_ep_exit(struct dw_pcie_ep *ep); |
cb22d40b | 550 | int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no); |
16093362 BH |
551 | int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, |
552 | u8 interrupt_num); | |
beb4641a GP |
553 | int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, |
554 | u16 interrupt_num); | |
2f7f7001 XB |
555 | int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, u8 func_no, |
556 | u16 interrupt_num); | |
9e718119 | 557 | void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar); |
47a06260 XB |
558 | struct dw_pcie_ep_func * |
559 | dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no); | |
f8aed6ec KVA |
560 | #else |
561 | static inline void dw_pcie_ep_linkup(struct dw_pcie_ep *ep) | |
562 | { | |
563 | } | |
564 | ||
565 | static inline int dw_pcie_ep_init(struct dw_pcie_ep *ep) | |
566 | { | |
567 | return 0; | |
568 | } | |
569 | ||
e966f739 VS |
570 | static inline int dw_pcie_ep_init_complete(struct dw_pcie_ep *ep) |
571 | { | |
572 | return 0; | |
573 | } | |
574 | ||
ac37dde7 VS |
575 | static inline void dw_pcie_ep_init_notify(struct dw_pcie_ep *ep) |
576 | { | |
577 | } | |
578 | ||
f8aed6ec KVA |
579 | static inline void dw_pcie_ep_exit(struct dw_pcie_ep *ep) |
580 | { | |
581 | } | |
9e718119 | 582 | |
cb22d40b GP |
583 | static inline int dw_pcie_ep_raise_legacy_irq(struct dw_pcie_ep *ep, u8 func_no) |
584 | { | |
585 | return 0; | |
586 | } | |
587 | ||
16093362 | 588 | static inline int dw_pcie_ep_raise_msi_irq(struct dw_pcie_ep *ep, u8 func_no, |
6f6d7873 NC |
589 | u8 interrupt_num) |
590 | { | |
591 | return 0; | |
592 | } | |
593 | ||
beb4641a GP |
594 | static inline int dw_pcie_ep_raise_msix_irq(struct dw_pcie_ep *ep, u8 func_no, |
595 | u16 interrupt_num) | |
596 | { | |
597 | return 0; | |
598 | } | |
599 | ||
2f7f7001 XB |
600 | static inline int dw_pcie_ep_raise_msix_irq_doorbell(struct dw_pcie_ep *ep, |
601 | u8 func_no, | |
602 | u16 interrupt_num) | |
603 | { | |
604 | return 0; | |
605 | } | |
606 | ||
9e718119 NC |
607 | static inline void dw_pcie_ep_reset_bar(struct dw_pcie *pci, enum pci_barno bar) |
608 | { | |
609 | } | |
47a06260 XB |
610 | |
611 | static inline struct dw_pcie_ep_func * | |
612 | dw_pcie_ep_get_func_from_ep(struct dw_pcie_ep *ep, u8 func_no) | |
613 | { | |
614 | return NULL; | |
615 | } | |
f8aed6ec | 616 | #endif |
18edf451 | 617 | #endif /* _PCIE_DESIGNWARE_H */ |