Merge https://gitlab.denx.de/u-boot/custodians/u-boot-marvell
[platform/kernel/u-boot.git] / drivers / pci / pcie_intel_fpga.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * Intel FPGA PCIe host controller driver
4  *
5  * Copyright (C) 2013-2018 Intel Corporation. All rights reserved
6  *
7  */
8
9 #include <common.h>
10 #include <dm.h>
11 #include <pci.h>
12 #include <asm/io.h>
13
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
26
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
35 #define RP_DEVFN                        0
36
37 #define RP_CFG_ADDR(pcie, reg)                                          \
38                 ((pcie->hip_base) + (reg) + (1 << 20))
39 #define RP_SECONDARY(pcie)                                              \
40         readb(RP_CFG_ADDR(pcie, PCI_SECONDARY_BUS))
41 #define TLP_REQ_ID(bus, devfn)          (((bus) << 8) | (devfn))
42
43 #define TLP_CFGRD_DW0(pcie, bus)                                        \
44         ((((bus > RP_SECONDARY(pcie)) ? TLP_FMTTYPE_CFGRD1              \
45                                       : TLP_FMTTYPE_CFGRD0) << 24) |    \
46                                         TLP_PAYLOAD_SIZE)
47
48 #define TLP_CFGWR_DW0(pcie, bus)                                        \
49         ((((bus > RP_SECONDARY(pcie)) ? TLP_FMTTYPE_CFGWR1              \
50                                       : TLP_FMTTYPE_CFGWR0) << 24) |    \
51                                         TLP_PAYLOAD_SIZE)
52
53 #define TLP_CFG_DW1(pcie, tag, be)                                      \
54         (((TLP_REQ_ID(pcie->first_busno,  RP_DEVFN)) << 16) | (tag << 8) | (be))
55 #define TLP_CFG_DW2(bus, dev, fn, offset)                               \
56         (((bus) << 24) | ((dev) << 19) | ((fn) << 16) | (offset))
57
58 #define TLP_COMP_STATUS(s)              (((s) >> 13) & 7)
59 #define TLP_BYTE_COUNT(s)               (((s) >> 0) & 0xfff)
60 #define TLP_HDR_SIZE                    3
61 #define TLP_LOOP                        20000
62 #define DWORD_MASK                      3
63
64 #define IS_ROOT_PORT(pcie, bdf)                         \
65                 ((PCI_BUS(bdf) == pcie->first_busno) ? true : false)
66
67 #define PCI_EXP_LNKSTA          18      /* Link Status */
68 #define PCI_EXP_LNKSTA_DLLLA    0x2000  /* Data Link Layer Link Active */
69
70 /**
71  * struct intel_fpga_pcie - Intel FPGA PCIe controller state
72  * @bus: Pointer to the PCI bus
73  * @cra_base: The base address of CRA register space
74  * @hip_base: The base address of Rootport configuration space
75  * @first_busno: This driver supports multiple PCIe controllers.
76  *               first_busno stores the bus number of the PCIe root-port
77  *               number which may vary depending on the PCIe setup.
78  */
79 struct intel_fpga_pcie {
80         struct udevice *bus;
81         void __iomem *cra_base;
82         void __iomem *hip_base;
83         int first_busno;
84 };
85
86 /**
87  * Intel FPGA PCIe port uses BAR0 of RC's configuration space as the
88  * translation from PCI bus to native BUS. Entire DDR region is mapped
89  * into PCIe space using these registers, so it can be reached by DMA from
90  * EP devices.
91  * The BAR0 of bridge should be hidden during enumeration to avoid the
92  * sizing and resource allocation by PCIe core.
93  */
94 static bool intel_fpga_pcie_hide_rc_bar(struct intel_fpga_pcie *pcie,
95                                         pci_dev_t bdf, int offset)
96 {
97         if (IS_ROOT_PORT(pcie, bdf) && PCI_DEV(bdf) == 0 &&
98             PCI_FUNC(bdf) == 0 && offset == PCI_BASE_ADDRESS_0)
99                 return true;
100
101         return false;
102 }
103
104 static inline void cra_writel(struct intel_fpga_pcie *pcie, const u32 value,
105                               const u32 reg)
106 {
107         writel(value, pcie->cra_base + reg);
108 }
109
110 static inline u32 cra_readl(struct intel_fpga_pcie *pcie, const u32 reg)
111 {
112         return readl(pcie->cra_base + reg);
113 }
114
115 static bool intel_fpga_pcie_link_up(struct intel_fpga_pcie *pcie)
116 {
117         return !!(readw(RP_CFG_ADDR(pcie, RP_CAP_OFFSET + PCI_EXP_LNKSTA))
118                         & PCI_EXP_LNKSTA_DLLLA);
119 }
120
121 static bool intel_fpga_pcie_addr_valid(struct intel_fpga_pcie *pcie,
122                                        pci_dev_t bdf)
123 {
124         /* If there is no link, then there is no device */
125         if (!IS_ROOT_PORT(pcie, bdf) && !intel_fpga_pcie_link_up(pcie))
126                 return false;
127
128         /* access only one slot on each root port */
129         if (IS_ROOT_PORT(pcie, bdf) && PCI_DEV(bdf) > 0)
130                 return false;
131
132         if ((PCI_BUS(bdf) == pcie->first_busno + 1) && PCI_DEV(bdf) > 0)
133                 return false;
134
135         return true;
136 }
137
138 static void tlp_write_tx(struct intel_fpga_pcie *pcie, u32 reg0, u32 ctrl)
139 {
140         cra_writel(pcie, reg0, RP_TX_REG0);
141         cra_writel(pcie, ctrl, RP_TX_CNTRL);
142 }
143
144 static int tlp_read_packet(struct intel_fpga_pcie *pcie, u32 *value)
145 {
146         int i;
147         u32 ctrl;
148         u32 comp_status;
149         u32 dw[4];
150         u32 count = 0;
151
152         for (i = 0; i < TLP_LOOP; i++) {
153                 ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
154                 if (!(ctrl & RP_RXCPL_SOP))
155                         continue;
156
157                 /* read first DW */
158                 dw[count++] = cra_readl(pcie, RP_RXCPL_REG);
159
160                 /* Poll for EOP */
161                 for (i = 0; i < TLP_LOOP; i++) {
162                         ctrl = cra_readl(pcie, RP_RXCPL_STATUS);
163                         dw[count++] = cra_readl(pcie, RP_RXCPL_REG);
164                         if (ctrl & RP_RXCPL_EOP) {
165                                 comp_status = TLP_COMP_STATUS(dw[1]);
166                                 if (comp_status) {
167                                         *value = pci_get_ff(PCI_SIZE_32);
168                                         return 0;
169                                 }
170
171                                 if (value &&
172                                     TLP_BYTE_COUNT(dw[1]) == sizeof(u32) &&
173                                     count >= 3)
174                                         *value = dw[3];
175
176                                 return 0;
177                         }
178                 }
179
180                 udelay(5);
181         }
182
183         dev_err(pcie->dev, "read TLP packet timed out\n");
184         return -ENODEV;
185 }
186
187 static void tlp_write_packet(struct intel_fpga_pcie *pcie, u32 *headers,
188                              u32 data)
189 {
190         tlp_write_tx(pcie, headers[0], RP_TX_SOP);
191
192         tlp_write_tx(pcie, headers[1], 0);
193
194         tlp_write_tx(pcie, headers[2], 0);
195
196         tlp_write_tx(pcie, data, RP_TX_EOP);
197 }
198
199 static int tlp_cfg_dword_read(struct intel_fpga_pcie *pcie, pci_dev_t bdf,
200                               int offset, u8 byte_en, u32 *value)
201 {
202         u32 headers[TLP_HDR_SIZE];
203         u8 busno = PCI_BUS(bdf);
204
205         headers[0] = TLP_CFGRD_DW0(pcie, busno);
206         headers[1] = TLP_CFG_DW1(pcie, TLP_READ_TAG, byte_en);
207         headers[2] = TLP_CFG_DW2(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
208
209         tlp_write_packet(pcie, headers, 0);
210
211         return tlp_read_packet(pcie, value);
212 }
213
214 static int tlp_cfg_dword_write(struct intel_fpga_pcie *pcie, pci_dev_t bdf,
215                                int offset, u8 byte_en, u32 value)
216 {
217         u32 headers[TLP_HDR_SIZE];
218         u8 busno = PCI_BUS(bdf);
219
220         headers[0] = TLP_CFGWR_DW0(pcie, busno);
221         headers[1] = TLP_CFG_DW1(pcie, TLP_WRITE_TAG, byte_en);
222         headers[2] = TLP_CFG_DW2(busno, PCI_DEV(bdf), PCI_FUNC(bdf), offset);
223
224         tlp_write_packet(pcie, headers, value);
225
226         return tlp_read_packet(pcie, NULL);
227 }
228
229 int intel_fpga_rp_conf_addr(struct udevice *bus, pci_dev_t bdf,
230                             uint offset, void **paddress)
231 {
232         struct intel_fpga_pcie *pcie = dev_get_priv(bus);
233
234         *paddress = RP_CFG_ADDR(pcie, offset);
235
236         return 0;
237 }
238
239 static int intel_fpga_pcie_rp_rd_conf(struct udevice *bus, pci_dev_t bdf,
240                                       uint offset, ulong *valuep,
241                                       enum pci_size_t size)
242 {
243         return pci_generic_mmap_read_config(bus, intel_fpga_rp_conf_addr,
244                                             bdf, offset, valuep, size);
245 }
246
247 static int intel_fpga_pcie_rp_wr_conf(struct udevice *bus, pci_dev_t bdf,
248                                       uint offset, ulong value,
249                                       enum pci_size_t size)
250 {
251         int ret;
252         struct intel_fpga_pcie *pcie = dev_get_priv(bus);
253
254         ret = pci_generic_mmap_write_config(bus, intel_fpga_rp_conf_addr,
255                                             bdf, offset, value, size);
256         if (!ret) {
257                 /* Monitor changes to PCI_PRIMARY_BUS register on root port
258                  * and update local copy of root bus number accordingly.
259                  */
260                 if (offset == PCI_PRIMARY_BUS)
261                         pcie->first_busno = (u8)(value);
262         }
263
264         return ret;
265 }
266
267 static u8 pcie_get_byte_en(uint offset, enum pci_size_t size)
268 {
269         switch (size) {
270         case PCI_SIZE_8:
271                 return 1 << (offset & 3);
272         case PCI_SIZE_16:
273                 return 3 << (offset & 3);
274         default:
275                 return 0xf;
276         }
277 }
278
279 static int _pcie_intel_fpga_read_config(struct intel_fpga_pcie *pcie,
280                                         pci_dev_t bdf, uint offset,
281                                         ulong *valuep, enum pci_size_t size)
282 {
283         int ret;
284         u32 data;
285         u8 byte_en;
286
287         /* Uses memory mapped method to read rootport config registers */
288         if (IS_ROOT_PORT(pcie, bdf))
289                 return intel_fpga_pcie_rp_rd_conf(pcie->bus, bdf,
290                                        offset, valuep, size);
291
292         byte_en = pcie_get_byte_en(offset, size);
293         ret = tlp_cfg_dword_read(pcie, bdf, offset & ~DWORD_MASK,
294                                  byte_en, &data);
295         if (ret)
296                 return ret;
297
298         dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08x)\n",
299                 offset, size, data);
300         *valuep = pci_conv_32_to_size(data, offset, size);
301
302         return 0;
303 }
304
305 static int _pcie_intel_fpga_write_config(struct intel_fpga_pcie *pcie,
306                                          pci_dev_t bdf, uint offset,
307                                          ulong value, enum pci_size_t size)
308 {
309         u32 data;
310         u8 byte_en;
311
312         dev_dbg(pcie->dev, "PCIE CFG write: (b.d.f)=(%02d.%02d.%02d)\n",
313                 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
314         dev_dbg(pcie->dev, "(addr,size,val)=(0x%04x, %d, 0x%08lx)\n",
315                 offset, size, value);
316
317         /* Uses memory mapped method to read rootport config registers */
318         if (IS_ROOT_PORT(pcie, bdf))
319                 return intel_fpga_pcie_rp_wr_conf(pcie->bus, bdf, offset,
320                                                   value, size);
321
322         byte_en = pcie_get_byte_en(offset, size);
323         data = pci_conv_size_to_32(0, value, offset, size);
324
325         return tlp_cfg_dword_write(pcie, bdf, offset & ~DWORD_MASK,
326                                    byte_en, data);
327 }
328
329 static int pcie_intel_fpga_read_config(struct udevice *bus, pci_dev_t bdf,
330                                        uint offset, ulong *valuep,
331                                        enum pci_size_t size)
332 {
333         struct intel_fpga_pcie *pcie = dev_get_priv(bus);
334
335         dev_dbg(pcie->dev, "PCIE CFG read:  (b.d.f)=(%02d.%02d.%02d)\n",
336                 PCI_BUS(bdf), PCI_DEV(bdf), PCI_FUNC(bdf));
337
338         if (intel_fpga_pcie_hide_rc_bar(pcie, bdf, offset)) {
339                 *valuep = (u32)pci_get_ff(size);
340                 return 0;
341         }
342
343         if (!intel_fpga_pcie_addr_valid(pcie, bdf)) {
344                 *valuep = (u32)pci_get_ff(size);
345                 return 0;
346         }
347
348         return _pcie_intel_fpga_read_config(pcie, bdf, offset, valuep, size);
349 }
350
351 static int pcie_intel_fpga_write_config(struct udevice *bus, pci_dev_t bdf,
352                                         uint offset, ulong value,
353                                         enum pci_size_t size)
354 {
355         struct intel_fpga_pcie *pcie = dev_get_priv(bus);
356
357         if (intel_fpga_pcie_hide_rc_bar(pcie, bdf, offset))
358                 return 0;
359
360         if (!intel_fpga_pcie_addr_valid(pcie, bdf))
361                 return 0;
362
363         return _pcie_intel_fpga_write_config(pcie, bdf, offset, value,
364                                           size);
365 }
366
367 static int pcie_intel_fpga_probe(struct udevice *dev)
368 {
369         struct intel_fpga_pcie *pcie = dev_get_priv(dev);
370
371         pcie->bus = pci_get_controller(dev);
372         pcie->first_busno = dev->seq;
373
374         /* clear all interrupts */
375         cra_writel(pcie, P2A_INT_STS_ALL, P2A_INT_STATUS);
376         /* disable all interrupts */
377         cra_writel(pcie, 0, P2A_INT_ENABLE);
378
379         return 0;
380 }
381
382 static int pcie_intel_fpga_ofdata_to_platdata(struct udevice *dev)
383 {
384         struct intel_fpga_pcie *pcie = dev_get_priv(dev);
385         struct fdt_resource reg_res;
386         int node = dev_of_offset(dev);
387         int ret;
388
389         DECLARE_GLOBAL_DATA_PTR;
390
391         ret = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names",
392                                      "Cra", &reg_res);
393         if (ret) {
394                 dev_err(dev, "resource \"Cra\" not found\n");
395                 return ret;
396         }
397
398         pcie->cra_base = map_physmem(reg_res.start,
399                                      fdt_resource_size(&reg_res),
400                                      MAP_NOCACHE);
401
402         ret = fdt_get_named_resource(gd->fdt_blob, node, "reg", "reg-names",
403                                      "Hip", &reg_res);
404         if (ret) {
405                 dev_err(dev, "resource \"Hip\" not found\n");
406                 return ret;
407         }
408
409         pcie->hip_base = map_physmem(reg_res.start,
410                                      fdt_resource_size(&reg_res),
411                                      MAP_NOCACHE);
412
413         return 0;
414 }
415
416 static const struct dm_pci_ops pcie_intel_fpga_ops = {
417         .read_config    = pcie_intel_fpga_read_config,
418         .write_config   = pcie_intel_fpga_write_config,
419 };
420
421 static const struct udevice_id pcie_intel_fpga_ids[] = {
422         { .compatible = "altr,pcie-root-port-2.0" },
423         {},
424 };
425
426 U_BOOT_DRIVER(pcie_intel_fpga) = {
427         .name                   = "pcie_intel_fpga",
428         .id                     = UCLASS_PCI,
429         .of_match               = pcie_intel_fpga_ids,
430         .ops                    = &pcie_intel_fpga_ops,
431         .ofdata_to_platdata     = pcie_intel_fpga_ofdata_to_platdata,
432         .probe                  = pcie_intel_fpga_probe,
433         .priv_auto_alloc_size   = sizeof(struct intel_fpga_pcie),
434 };