1 // SPDX-License-Identifier: GPL-2.0
3 * Intel FPGA PCIe host controller driver
5 * Copyright (C) 2013-2018 Intel Corporation. All rights reserved
13 #include <dm/device_compat.h>
14 #include <linux/delay.h>
16 #define RP_TX_REG0 0x2000
17 #define RP_TX_CNTRL 0x2004
18 #define RP_TX_SOP BIT(0)
19 #define RP_TX_EOP BIT(1)
20 #define RP_RXCPL_STATUS 0x200C
21 #define RP_RXCPL_SOP BIT(0)
22 #define RP_RXCPL_EOP BIT(1)
23 #define RP_RXCPL_REG 0x2008
24 #define P2A_INT_STATUS 0x3060
25 #define P2A_INT_STS_ALL 0xf
26 #define P2A_INT_ENABLE 0x3070
27 #define RP_CAP_OFFSET 0x70
29 /* TLP configuration type 0 and 1 */
30 #define TLP_FMTTYPE_CFGRD0 0x04 /* Configuration Read Type 0 */
31 #define TLP_FMTTYPE_CFGWR0 0x44 /* Configuration Write Type 0 */
32 #define TLP_FMTTYPE_CFGRD1 0x05 /* Configuration Read Type 1 */
33 #define TLP_FMTTYPE_CFGWR1 0x45 /* Configuration Write Type 1 */
34 #define TLP_PAYLOAD_SIZE 0x01
35 #define TLP_READ_TAG 0x1d
36 #define TLP_WRITE_TAG 0x10
39 #define RP_CFG_ADDR(pcie, reg) \
40 ((pcie->hip_base) + (reg) + (1 << 20))
41 #define RP_SECONDARY(pcie) \
42 readb(RP_CFG_ADDR(pcie, PCI_SECONDARY_BUS))
43 #define TLP_REQ_ID(bus, devfn) (((bus) << 8) | (devfn))
45 #define TLP_CFGRD_DW0(pcie, bus) \
46 ((((bus > RP_SECONDARY(pcie)) ? TLP_FMTTYPE_CFGRD1 \
47 : TLP_FMTTYPE_CFGRD0) << 24) | \
50 #define TLP_CFGWR_DW0(pcie, bus) \
51 ((((bus > RP_SECONDARY(pcie)) ? TLP_FMTTYPE_CFGWR1 \
52 : TLP_FMTTYPE_CFGWR0) << 24) | \
55 #define TLP_CFG_DW1(pcie, tag, be) \
56 (((TLP_REQ_ID(pcie->first_busno, RP_DEVFN)) << 16) | (tag << 8) | (be))
57 #define TLP_CFG_DW2(bus, dev, fn, offset) \
58 (((bus) << 24) | ((dev) << 19) | ((fn) << 16) | (offset))
60 #define TLP_COMP_STATUS(s) (((s) >> 13) & 7)
61 #define TLP_BYTE_COUNT(s) (((s) >> 0) & 0xfff)
62 #define TLP_HDR_SIZE 3
63 #define TLP_LOOP 20000
66 #define IS_ROOT_PORT(pcie, bdf) \
67 ((PCI_BUS(bdf) == pcie->first_busno) ? true : false)
69 #define PCI_EXP_LNKSTA 18 /* Link Status */
70 #define PCI_EXP_LNKSTA_DLLLA 0x2000 /* Data Link Layer Link Active */
73 * struct intel_fpga_pcie - Intel FPGA PCIe controller state
74 * @bus: Pointer to the PCI bus
75 * @cra_base: The base address of CRA register space
76 * @hip_base: The base address of Rootport configuration space
77 * @first_busno: This driver supports multiple PCIe controllers.
78 * first_busno stores the bus number of the PCIe root-port
79 * number which may vary depending on the PCIe setup.
81 struct intel_fpga_pcie {
83 void __iomem *cra_base;
84 void __iomem *hip_base;
89 * Intel FPGA PCIe port uses BAR0 of RC's configuration space as the
90 * translation from PCI bus to native BUS. Entire DDR region is mapped
91 * into PCIe space using these registers, so it can be reached by DMA from
93 * The BAR0 of bridge should be hidden during enumeration to avoid the
94 * sizing and resource allocation by PCIe core.
96 static bool intel_fpga_pcie_hide_rc_bar(struct intel_fpga_pcie *pcie,
97 pci_dev_t bdf, int offset)
99 if (IS_ROOT_PORT(pcie, bdf) && PCI_DEV(bdf) == 0 &&
100 PCI_FUNC(bdf) == 0 && offset == PCI_BASE_ADDRESS_0)
106 static inline void cra_writel(struct intel_fpga_pcie *pcie, const u32 value,
109 writel(value, pcie->cra_base + reg);
112 static inline u32 cra_readl(struct intel_fpga_pcie *pcie, const u32 reg)
114 return readl(pcie->cra_base + reg);
117 static bool intel_fpga_pcie_link_up(struct intel_fpga_pcie *pcie)
119 return !!(readw(RP_CFG_ADDR(pcie, RP_CAP_OFFSET + PCI_EXP_LNKSTA))
120 & PCI_EXP_LNKSTA_DLLLA);
123 static bool intel_fpga_pcie_addr_valid(struct intel_fpga_pcie *pcie,
126 /* If there is no link, then there is no device */
127 if (!IS_ROOT_PORT(pcie, bdf) && !intel_fpga_pcie_link_up(pcie))
130 /* access only one slot on each root port */
131 if (IS_ROOT_PORT(pcie, bdf) && PCI_DEV(bdf) > 0)
134 if ((PCI_BUS(bdf) == pcie->first_busno + 1) && PCI_DEV(bdf) > 0)
140 static void tlp_write_tx(struct intel_fpga_pcie *pcie, u32 reg0, u32 ctrl)
142 cra_writel(pcie, reg0, RP_TX_REG0);
143 cra_writel(pcie, ctrl, RP_TX_CNTRL);
146 static int tlp_read_packet(struct intel_fpga_pcie *pcie, u32 *value)
154 for (i = 0; i < TLP_LOOP; i++) {
155 ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
156 if (!(ctrl & RP_RXCPL_SOP))
160 dw[count++] = cra_readl(pcie, RP_RXCPL_REG);
163 for (i = 0; i < TLP_LOOP; i++) {
164 ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
165 dw[count++] = cra_readl(pcie, RP_RXCPL_REG);
166 if (ctrl & RP_RXCPL_EOP) {
167 comp_status = TLP_COMP_STATUS(dw[1]);
169 *value = pci_get_ff(PCI_SIZE_32);
174 TLP_BYTE_COUNT(dw[1]) == sizeof(u32) &&
185 dev_err(pcie->dev, "read TLP packet timed out\n");
189 static void tlp_write_packet(struct intel_fpga_pcie *pcie, u32 *headers,
192 tlp_write_tx(pcie, headers[0], RP_TX_SOP);
194 tlp_write_tx(pcie, headers[1], 0);
196 tlp_write_tx(pcie, headers[2], 0);
198 tlp_write_tx(pcie, data, RP_TX_EOP);
201 static int tlp_cfg_dword_read(struct intel_fpga_pcie *pcie, pci_dev_t bdf,
202 int offset, u8 byte_en, u32 *value)
204 u32 headers[TLP_HDR_SIZE];
205 u8 busno = PCI_BUS(bdf);
207 headers[0] = TLP_CFGRD_DW0(pcie, busno);
208 headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en);
209 headers[2] = TLP_CFG_DW2(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
211 tlp_write_packet(pcie, headers, 0);
213 return tlp_read_packet(pcie, value);
216 static int tlp_cfg_dword_write(struct intel_fpga_pcie *pcie, pci_dev_t bdf,
217 int offset, u8 byte_en, u32 value)
219 u32 headers[TLP_HDR_SIZE];
220 u8 busno = PCI_BUS(bdf);
222 headers[0] = TLP_CFGWR_DW0(pcie, busno);
223 headers[1] = TLP_CFG_DW1(pcie, TLP_WRITE_TAG, byte_en);
224 headers[2] = TLP_CFG_DW2(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
226 tlp_write_packet(pcie, headers, value);
228 return tlp_read_packet(pcie, NULL);
231 int intel_fpga_rp_conf_addr(const struct udevice *bus, pci_dev_t bdf,
232 uint offset, void **paddress)
234 struct intel_fpga_pcie *pcie = dev_get_priv(bus);
236 *paddress = RP_CFG_ADDR(pcie, offset);
241 static int intel_fpga_pcie_rp_rd_conf(struct udevice *bus, pci_dev_t bdf,
242 uint offset, ulong *valuep,
243 enum pci_size_t size)
245 return pci_generic_mmap_read_config(bus, intel_fpga_rp_conf_addr,
246 bdf, offset, valuep, size);
249 static int intel_fpga_pcie_rp_wr_conf(struct udevice *bus, pci_dev_t bdf,
250 uint offset, ulong value,
251 enum pci_size_t size)
254 struct intel_fpga_pcie *pcie = dev_get_priv(bus);
256 ret = pci_generic_mmap_write_config(bus, intel_fpga_rp_conf_addr,
257 bdf, offset, value, size);
259 /* Monitor changes to PCI_PRIMARY_BUS register on root port
260 * and update local copy of root bus number accordingly.
262 if (offset == PCI_PRIMARY_BUS)
263 pcie->first_busno = (u8)(value);
269 static u8 pcie_get_byte_en(uint offset, enum pci_size_t size)
273 return 1 << (offset & 3);
275 return 3 << (offset & 3);
281 static int _pcie_intel_fpga_read_config(struct intel_fpga_pcie *pcie,
282 pci_dev_t bdf, uint offset,
283 ulong *valuep, enum pci_size_t size)
289 /* Uses memory mapped method to read rootport config registers */
290 if (IS_ROOT_PORT(pcie, bdf))
291 return intel_fpga_pcie_rp_rd_conf(pcie->bus, bdf,
292 offset, valuep, size);
294 byte_en = pcie_get_byte_en(offset, size);
295 ret = tlp_cfg_dword_read(pcie, bdf, offset & ~DWORD_MASK,
300 dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08x)\n",
302 *valuep = pci_conv_32_to_size(data, offset, size);
307 static int _pcie_intel_fpga_write_config(struct intel_fpga_pcie *pcie,
308 pci_dev_t bdf, uint offset,
309 ulong value, enum pci_size_t size)
314 dev_dbg(pcie->dev, "PCIE CFG write: (b.d.f)=(%02d.%02d.%02d)\n",
315 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
316 dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08lx)\n",
317 offset, size, value);
319 /* Uses memory mapped method to read rootport config registers */
320 if (IS_ROOT_PORT(pcie, bdf))
321 return intel_fpga_pcie_rp_wr_conf(pcie->bus, bdf, offset,
324 byte_en = pcie_get_byte_en(offset, size);
325 data = pci_conv_size_to_32(0, value, offset, size);
327 return tlp_cfg_dword_write(pcie, bdf, offset & ~DWORD_MASK,
331 static int pcie_intel_fpga_read_config(const struct udevice *bus, pci_dev_t bdf,
332 uint offset, ulong *valuep,
333 enum pci_size_t size)
335 struct intel_fpga_pcie *pcie = dev_get_priv(bus);
337 dev_dbg(pcie->dev, "PCIE CFG read: (b.d.f)=(%02d.%02d.%02d)\n",
338 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
340 if (intel_fpga_pcie_hide_rc_bar(pcie, bdf, offset)) {
341 *valuep = (u32)pci_get_ff(size);
345 if (!intel_fpga_pcie_addr_valid(pcie, bdf)) {
346 *valuep = (u32)pci_get_ff(size);
350 return _pcie_intel_fpga_read_config(pcie, bdf, offset, valuep, size);
353 static int pcie_intel_fpga_write_config(struct udevice *bus, pci_dev_t bdf,
354 uint offset, ulong value,
355 enum pci_size_t size)
357 struct intel_fpga_pcie *pcie = dev_get_priv(bus);
359 if (intel_fpga_pcie_hide_rc_bar(pcie, bdf, offset))
362 if (!intel_fpga_pcie_addr_valid(pcie, bdf))
365 return _pcie_intel_fpga_write_config(pcie, bdf, offset, value,
369 static int pcie_intel_fpga_probe(struct udevice *dev)
371 struct intel_fpga_pcie *pcie = dev_get_priv(dev);
373 pcie->bus = pci_get_controller(dev);
374 pcie->first_busno = dev->seq;
376 /* clear all interrupts */
377 cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
378 /* disable all interrupts */
379 cra_writel(pcie, 0, P2A_INT_ENABLE);
384 static int pcie_intel_fpga_ofdata_to_platdata(struct udevice *dev)
386 struct intel_fpga_pcie *pcie = dev_get_priv(dev);
387 struct fdt_resource reg_res;
388 int node = dev_of_offset(dev);
391 DECLARE_GLOBAL_DATA_PTR;
393 ret = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names",
396 dev_err(dev, "resource \"Cra\" not found\n");
400 pcie->cra_base = map_physmem(reg_res.start,
401 fdt_resource_size(®_res),
404 ret = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names",
407 dev_err(dev, "resource \"Hip\" not found\n");
411 pcie->hip_base = map_physmem(reg_res.start,
412 fdt_resource_size(®_res),
418 static const struct dm_pci_ops pcie_intel_fpga_ops = {
419 .read_config = pcie_intel_fpga_read_config,
420 .write_config = pcie_intel_fpga_write_config,
423 static const struct udevice_id pcie_intel_fpga_ids[] = {
424 { .compatible = "altr,pcie-root-port-2.0" },
428 U_BOOT_DRIVER(pcie_intel_fpga) = {
429 .name = "pcie_intel_fpga",
431 .of_match = pcie_intel_fpga_ids,
432 .ops = &pcie_intel_fpga_ops,
433 .ofdata_to_platdata = pcie_intel_fpga_ofdata_to_platdata,
434 .probe = pcie_intel_fpga_probe,
435 .priv_auto_alloc_size = sizeof(struct intel_fpga_pcie),