1 // SPDX-License-Identifier: GPL-2.0
3 * Intel FPGA PCIe host controller driver
5 * Copyright (C) 2013-2018 Intel Corporation. All rights reserved
14 #define RP_TX_REG0 0x2000
15 #define RP_TX_CNTRL 0x2004
16 #define RP_TX_SOP BIT(0)
17 #define RP_TX_EOP BIT(1)
18 #define RP_RXCPL_STATUS 0x200C
19 #define RP_RXCPL_SOP BIT(0)
20 #define RP_RXCPL_EOP BIT(1)
21 #define RP_RXCPL_REG 0x2008
22 #define P2A_INT_STATUS 0x3060
23 #define P2A_INT_STS_ALL 0xf
24 #define P2A_INT_ENABLE 0x3070
25 #define RP_CAP_OFFSET 0x70
27 /* TLP configuration type 0 and 1 */
28 #define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */
29 #define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */
30 #define TLP_FMTTYPE_CFGRD1 0x05 /* Configuration Read Type 1 */
31 #define TLP_FMTTYPE_CFGWR1 0x45 /* Configuration Write Type 1 */
32 #define TLP_PAYLOAD_SIZE 0x01
33 #define TLP_READ_TAG 0x1d
34 #define TLP_WRITE_TAG 0x10
37 #define RP_CFG_ADDR(pcie, reg) \
38 ((pcie->hip_base) + (reg) + (1 << 20))
39 #define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn))
41 #define TLP_CFGRD_DW0(pcie, bus) \
42 ((((bus != pcie->first_busno) ? TLP_FMTTYPE_CFGRD0 \
43 : TLP_FMTTYPE_CFGRD1) << 24) | \
46 #define TLP_CFGWR_DW0(pcie, bus) \
47 ((((bus != pcie->first_busno) ? TLP_FMTTYPE_CFGWR0 \
48 : TLP_FMTTYPE_CFGWR1) << 24) | \
51 #define TLP_CFG_DW1(pcie, tag, be) \
52 (((TLP_REQ_ID(pcie->first_busno, RP_DEVFN)) << 16) | (tag << 8) | (be))
53 #define TLP_CFG_DW2(bus, dev, fn, offset) \
54 (((bus) << 24) | ((dev) << 19) | ((fn) << 16) | (offset))
56 #define TLP_COMP_STATUS(s) (((s) >> 13) & 7)
57 #define TLP_BYTE_COUNT(s) (((s) >> 0) & 0xfff)
58 #define TLP_HDR_SIZE 3
62 #define IS_ROOT_PORT(pcie, bdf) \
63 ((PCI_BUS(bdf) == pcie->first_busno) ? true : false)
65 #define PCI_EXP_LNKSTA 18 /* Link Status */
66 #define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */
69 * struct intel_fpga_pcie - Intel FPGA PCIe controller state
70 * @bus: Pointer to the PCI bus
71 * @cra_base: The base address of CRA register space
72 * @hip_base: The base address of Rootport configuration space
73 * @first_busno: This driver supports multiple PCIe controllers.
74 * first_busno stores the bus number of the PCIe root-port
75 * number which may vary depending on the PCIe setup.
77 struct intel_fpga_pcie
{
79 void __iomem
*cra_base
;
80 void __iomem
*hip_base
;
85 * Intel FPGA PCIe port uses BAR0 of RC's configuration space as the
86 * translation from PCI bus to native BUS. Entire DDR region is mapped
87 * into PCIe space using these registers, so it can be reached by DMA from
89 * The BAR0 of bridge should be hidden during enumeration to avoid the
90 * sizing and resource allocation by PCIe core.
92 static bool intel_fpga_pcie_hide_rc_bar(struct intel_fpga_pcie
*pcie
,
93 pci_dev_t bdf
, int offset
)
95 if (IS_ROOT_PORT(pcie
, bdf
) && PCI_DEV(bdf
) == 0 &&
96 PCI_FUNC(bdf
) == 0 && offset
== PCI_BASE_ADDRESS_0
)
102 static inline void cra_writel(struct intel_fpga_pcie
*pcie
, const u32 value
,
105 writel(value
, pcie
->cra_base
+ reg
);
108 static inline u32
cra_readl(struct intel_fpga_pcie
*pcie
, const u32 reg
)
110 return readl(pcie
->cra_base
+ reg
);
113 static bool intel_fpga_pcie_link_up(struct intel_fpga_pcie
*pcie
)
115 return !!(readw(RP_CFG_ADDR(pcie
, RP_CAP_OFFSET
+ PCI_EXP_LNKSTA
))
116 & PCI_EXP_LNKSTA_DLLLA
);
119 static bool intel_fpga_pcie_addr_valid(struct intel_fpga_pcie
*pcie
,
122 /* If there is no link, then there is no device */
123 if (!IS_ROOT_PORT(pcie
, bdf
) && !intel_fpga_pcie_link_up(pcie
))
126 /* access only one slot on each root port */
127 if (IS_ROOT_PORT(pcie
, bdf
) && PCI_DEV(bdf
) > 0)
130 if ((PCI_BUS(bdf
) == pcie
->first_busno
+ 1) && PCI_DEV(bdf
) > 0)
136 static void tlp_write_tx(struct intel_fpga_pcie
*pcie
, u32 reg0
, u32 ctrl
)
138 cra_writel(pcie
, reg0
, RP_TX_REG0
);
139 cra_writel(pcie
, ctrl
, RP_TX_CNTRL
);
142 static int tlp_read_packet(struct intel_fpga_pcie
*pcie
, u32
*value
)
150 for (i
= 0; i
< TLP_LOOP
; i
++) {
151 ctrl
= cra_readl(pcie
, RP_RXCPL_STATUS
);
152 if (!(ctrl
& RP_RXCPL_SOP
))
156 dw
[count
++] = cra_readl(pcie
, RP_RXCPL_REG
);
159 for (i
= 0; i
< TLP_LOOP
; i
++) {
160 ctrl
= cra_readl(pcie
, RP_RXCPL_STATUS
);
161 dw
[count
++] = cra_readl(pcie
, RP_RXCPL_REG
);
162 if (ctrl
& RP_RXCPL_EOP
) {
163 comp_status
= TLP_COMP_STATUS(dw
[1]);
168 TLP_BYTE_COUNT(dw
[1]) == sizeof(u32
) &&
179 dev_err(pcie
->dev
, "read TLP packet timed out\n");
183 static void tlp_write_packet(struct intel_fpga_pcie
*pcie
, u32
*headers
,
186 tlp_write_tx(pcie
, headers
[0], RP_TX_SOP
);
188 tlp_write_tx(pcie
, headers
[1], 0);
190 tlp_write_tx(pcie
, headers
[2], 0);
192 tlp_write_tx(pcie
, data
, RP_TX_EOP
);
195 static int tlp_cfg_dword_read(struct intel_fpga_pcie
*pcie
, pci_dev_t bdf
,
196 int offset
, u8 byte_en
, u32
*value
)
198 u32 headers
[TLP_HDR_SIZE
];
199 u8 busno
= PCI_BUS(bdf
);
201 headers
[0] = TLP_CFGRD_DW0(pcie
, busno
);
202 headers
[1] = TLP_CFG_DW1(pcie
, TLP_READ_TAG
, byte_en
);
203 headers
[2] = TLP_CFG_DW2(busno
, PCI_DEV(bdf
), PCI_FUNC(bdf
), offset
);
205 tlp_write_packet(pcie
, headers
, 0);
207 return tlp_read_packet(pcie
, value
);
210 static int tlp_cfg_dword_write(struct intel_fpga_pcie
*pcie
, pci_dev_t bdf
,
211 int offset
, u8 byte_en
, u32 value
)
213 u32 headers
[TLP_HDR_SIZE
];
214 u8 busno
= PCI_BUS(bdf
);
216 headers
[0] = TLP_CFGWR_DW0(pcie
, busno
);
217 headers
[1] = TLP_CFG_DW1(pcie
, TLP_WRITE_TAG
, byte_en
);
218 headers
[2] = TLP_CFG_DW2(busno
, PCI_DEV(bdf
), PCI_FUNC(bdf
), offset
);
220 tlp_write_packet(pcie
, headers
, value
);
222 return tlp_read_packet(pcie
, NULL
);
225 int intel_fpga_rp_conf_addr(struct udevice
*bus
, pci_dev_t bdf
,
226 uint offset
, void **paddress
)
228 struct intel_fpga_pcie
*pcie
= dev_get_priv(bus
);
230 *paddress
= RP_CFG_ADDR(pcie
, offset
);
235 static int intel_fpga_pcie_rp_rd_conf(struct udevice
*bus
, pci_dev_t bdf
,
236 uint offset
, ulong
*valuep
,
237 enum pci_size_t size
)
239 return pci_generic_mmap_read_config(bus
, intel_fpga_rp_conf_addr
,
240 bdf
, offset
, valuep
, size
);
243 static int intel_fpga_pcie_rp_wr_conf(struct udevice
*bus
, pci_dev_t bdf
,
244 uint offset
, ulong value
,
245 enum pci_size_t size
)
248 struct intel_fpga_pcie
*pcie
= dev_get_priv(bus
);
250 ret
= pci_generic_mmap_write_config(bus
, intel_fpga_rp_conf_addr
,
251 bdf
, offset
, value
, size
);
253 /* Monitor changes to PCI_PRIMARY_BUS register on root port
254 * and update local copy of root bus number accordingly.
256 if (offset
== PCI_PRIMARY_BUS
)
257 pcie
->first_busno
= (u8
)(value
);
263 static u8
pcie_get_byte_en(uint offset
, enum pci_size_t size
)
267 return 1 << (offset
& 3);
269 return 3 << (offset
& 3);
275 static int _pcie_intel_fpga_read_config(struct intel_fpga_pcie
*pcie
,
276 pci_dev_t bdf
, uint offset
,
277 ulong
*valuep
, enum pci_size_t size
)
283 /* Uses memory mapped method to read rootport config registers */
284 if (IS_ROOT_PORT(pcie
, bdf
))
285 return intel_fpga_pcie_rp_rd_conf(pcie
->bus
, bdf
,
286 offset
, valuep
, size
);
288 byte_en
= pcie_get_byte_en(offset
, size
);
289 ret
= tlp_cfg_dword_read(pcie
, bdf
, offset
& ~DWORD_MASK
,
294 dev_dbg(pcie
->dev
, "(addr,size,val)=(0x%04x, %d, 0x%08x)\n",
296 *valuep
= pci_conv_32_to_size(data
, offset
, size
);
301 static int _pcie_intel_fpga_write_config(struct intel_fpga_pcie
*pcie
,
302 pci_dev_t bdf
, uint offset
,
303 ulong value
, enum pci_size_t size
)
308 dev_dbg(pcie
->dev
, "PCIE CFG write: (b.d.f)=(%02d.%02d.%02d)\n",
309 PCI_BUS(bdf
), PCI_DEV(bdf
), PCI_FUNC(bdf
));
310 dev_dbg(pcie
->dev
, "(addr,size,val)=(0x%04x, %d, 0x%08lx)\n",
311 offset
, size
, value
);
313 /* Uses memory mapped method to read rootport config registers */
314 if (IS_ROOT_PORT(pcie
, bdf
))
315 return intel_fpga_pcie_rp_wr_conf(pcie
->bus
, bdf
, offset
,
318 byte_en
= pcie_get_byte_en(offset
, size
);
319 data
= pci_conv_size_to_32(0, value
, offset
, size
);
321 return tlp_cfg_dword_write(pcie
, bdf
, offset
& ~DWORD_MASK
,
325 static int pcie_intel_fpga_read_config(struct udevice
*bus
, pci_dev_t bdf
,
326 uint offset
, ulong
*valuep
,
327 enum pci_size_t size
)
329 struct intel_fpga_pcie
*pcie
= dev_get_priv(bus
);
331 dev_dbg(pcie
->dev
, "PCIE CFG read: (b.d.f)=(%02d.%02d.%02d)\n",
332 PCI_BUS(bdf
), PCI_DEV(bdf
), PCI_FUNC(bdf
));
334 if (intel_fpga_pcie_hide_rc_bar(pcie
, bdf
, offset
)) {
335 *valuep
= (u32
)pci_get_ff(size
);
339 if (!intel_fpga_pcie_addr_valid(pcie
, bdf
)) {
340 *valuep
= (u32
)pci_get_ff(size
);
344 return _pcie_intel_fpga_read_config(pcie
, bdf
, offset
, valuep
, size
);
347 static int pcie_intel_fpga_write_config(struct udevice
*bus
, pci_dev_t bdf
,
348 uint offset
, ulong value
,
349 enum pci_size_t size
)
351 struct intel_fpga_pcie
*pcie
= dev_get_priv(bus
);
353 if (intel_fpga_pcie_hide_rc_bar(pcie
, bdf
, offset
))
356 if (!intel_fpga_pcie_addr_valid(pcie
, bdf
))
359 return _pcie_intel_fpga_write_config(pcie
, bdf
, offset
, value
,
363 static int pcie_intel_fpga_probe(struct udevice
*dev
)
365 struct intel_fpga_pcie
*pcie
= dev_get_priv(dev
);
367 pcie
->bus
= pci_get_controller(dev
);
368 pcie
->first_busno
= dev
->seq
;
370 /* clear all interrupts */
371 cra_writel(pcie
, P2A_INT_STS_ALL
, P2A_INT_STATUS
);
372 /* disable all interrupts */
373 cra_writel(pcie
, 0, P2A_INT_ENABLE
);
378 static int pcie_intel_fpga_ofdata_to_platdata(struct udevice
*dev
)
380 struct intel_fpga_pcie
*pcie
= dev_get_priv(dev
);
381 struct fdt_resource reg_res
;
382 int node
= dev_of_offset(dev
);
385 DECLARE_GLOBAL_DATA_PTR
;
387 ret
= fdt_get_named_resource(gd
->fdt_blob
, node
, "reg", "reg-names",
390 dev_err(dev
, "resource \"Cra\" not found\n");
394 pcie
->cra_base
= map_physmem(reg_res
.start
,
395 fdt_resource_size(®_res
),
398 ret
= fdt_get_named_resource(gd
->fdt_blob
, node
, "reg", "reg-names",
401 dev_err(dev
, "resource \"Hip\" not found\n");
405 pcie
->hip_base
= map_physmem(reg_res
.start
,
406 fdt_resource_size(®_res
),
412 static const struct dm_pci_ops pcie_intel_fpga_ops
= {
413 .read_config
= pcie_intel_fpga_read_config
,
414 .write_config
= pcie_intel_fpga_write_config
,
417 static const struct udevice_id pcie_intel_fpga_ids
[] = {
418 { .compatible
= "altr,pcie-root-port-2.0" },
422 U_BOOT_DRIVER(pcie_intel_fpga
) = {
423 .name
= "pcie_intel_fpga",
425 .of_match
= pcie_intel_fpga_ids
,
426 .ops
= &pcie_intel_fpga_ops
,
427 .ofdata_to_platdata
= pcie_intel_fpga_ofdata_to_platdata
,
428 .probe
= pcie_intel_fpga_probe
,
429 .priv_auto_alloc_size
= sizeof(struct intel_fpga_pcie
),