Merge tag 'timers-v5.9' of https://git.linaro.org/people/daniel.lezcano/linux into...
[linux-2.6-microblaze.git] / drivers / pci / controller / dwc / pcie-al.c
1 // SPDX-License-Identifier: GPL-2.0
2 /*
3  * PCIe host controller driver for Amazon's Annapurna Labs IP (used in chips
4  * such as Graviton and Alpine)
5  *
6  * Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
7  *
8  * Author: Jonathan Chocron <jonnyc@amazon.com>
9  */
10
11 #include <linux/pci.h>
12 #include <linux/pci-ecam.h>
13 #include <linux/pci-acpi.h>
14 #include "../../pci.h"
15
16 #if defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS)
17
18 struct al_pcie_acpi  {
19         void __iomem *dbi_base;
20 };
21
22 static void __iomem *al_pcie_map_bus(struct pci_bus *bus, unsigned int devfn,
23                                      int where)
24 {
25         struct pci_config_window *cfg = bus->sysdata;
26         struct al_pcie_acpi *pcie = cfg->priv;
27         void __iomem *dbi_base = pcie->dbi_base;
28
29         if (bus->number == cfg->busr.start) {
30                 /*
31                  * The DW PCIe core doesn't filter out transactions to other
32                  * devices/functions on the root bus num, so we do this here.
33                  */
34                 if (PCI_SLOT(devfn) > 0)
35                         return NULL;
36                 else
37                         return dbi_base + where;
38         }
39
40         return pci_ecam_map_bus(bus, devfn, where);
41 }
42
43 static int al_pcie_init(struct pci_config_window *cfg)
44 {
45         struct device *dev = cfg->parent;
46         struct acpi_device *adev = to_acpi_device(dev);
47         struct acpi_pci_root *root = acpi_driver_data(adev);
48         struct al_pcie_acpi *al_pcie;
49         struct resource *res;
50         int ret;
51
52         al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL);
53         if (!al_pcie)
54                 return -ENOMEM;
55
56         res = devm_kzalloc(dev, sizeof(*res), GFP_KERNEL);
57         if (!res)
58                 return -ENOMEM;
59
60         ret = acpi_get_rc_resources(dev, "AMZN0001", root->segment, res);
61         if (ret) {
62                 dev_err(dev, "can't get rc dbi base address for SEG %d\n",
63                         root->segment);
64                 return ret;
65         }
66
67         dev_dbg(dev, "Root port dbi res: %pR\n", res);
68
69         al_pcie->dbi_base = devm_pci_remap_cfg_resource(dev, res);
70         if (IS_ERR(al_pcie->dbi_base)) {
71                 long err = PTR_ERR(al_pcie->dbi_base);
72
73                 dev_err(dev, "couldn't remap dbi base %pR (err:%ld)\n",
74                         res, err);
75                 return err;
76         }
77
78         cfg->priv = al_pcie;
79
80         return 0;
81 }
82
83 const struct pci_ecam_ops al_pcie_ops = {
84         .bus_shift    = 20,
85         .init         =  al_pcie_init,
86         .pci_ops      = {
87                 .map_bus    = al_pcie_map_bus,
88                 .read       = pci_generic_config_read,
89                 .write      = pci_generic_config_write,
90         }
91 };
92
93 #endif /* defined(CONFIG_ACPI) && defined(CONFIG_PCI_QUIRKS) */
94
95 #ifdef CONFIG_PCIE_AL
96
97 #include <linux/of_pci.h>
98 #include "pcie-designware.h"
99
100 #define AL_PCIE_REV_ID_2        2
101 #define AL_PCIE_REV_ID_3        3
102 #define AL_PCIE_REV_ID_4        4
103
104 #define AXI_BASE_OFFSET         0x0
105
106 #define DEVICE_ID_OFFSET        0x16c
107
108 #define DEVICE_REV_ID                   0x0
109 #define DEVICE_REV_ID_DEV_ID_MASK       GENMASK(31, 16)
110
111 #define DEVICE_REV_ID_DEV_ID_X4         0
112 #define DEVICE_REV_ID_DEV_ID_X8         2
113 #define DEVICE_REV_ID_DEV_ID_X16        4
114
115 #define OB_CTRL_REV1_2_OFFSET   0x0040
116 #define OB_CTRL_REV3_5_OFFSET   0x0030
117
118 #define CFG_TARGET_BUS                  0x0
119 #define CFG_TARGET_BUS_MASK_MASK        GENMASK(7, 0)
120 #define CFG_TARGET_BUS_BUSNUM_MASK      GENMASK(15, 8)
121
122 #define CFG_CONTROL                     0x4
123 #define CFG_CONTROL_SUBBUS_MASK         GENMASK(15, 8)
124 #define CFG_CONTROL_SEC_BUS_MASK        GENMASK(23, 16)
125
126 struct al_pcie_reg_offsets {
127         unsigned int ob_ctrl;
128 };
129
130 struct al_pcie_target_bus_cfg {
131         u8 reg_val;
132         u8 reg_mask;
133         u8 ecam_mask;
134 };
135
136 struct al_pcie {
137         struct dw_pcie *pci;
138         void __iomem *controller_base; /* base of PCIe unit (not DW core) */
139         struct device *dev;
140         resource_size_t ecam_size;
141         unsigned int controller_rev_id;
142         struct al_pcie_reg_offsets reg_offsets;
143         struct al_pcie_target_bus_cfg target_bus_cfg;
144 };
145
146 #define PCIE_ECAM_DEVFN(x)              (((x) & 0xff) << 12)
147
148 #define to_al_pcie(x)           dev_get_drvdata((x)->dev)
149
150 static inline u32 al_pcie_controller_readl(struct al_pcie *pcie, u32 offset)
151 {
152         return readl_relaxed(pcie->controller_base + offset);
153 }
154
155 static inline void al_pcie_controller_writel(struct al_pcie *pcie, u32 offset,
156                                              u32 val)
157 {
158         writel_relaxed(val, pcie->controller_base + offset);
159 }
160
161 static int al_pcie_rev_id_get(struct al_pcie *pcie, unsigned int *rev_id)
162 {
163         u32 dev_rev_id_val;
164         u32 dev_id_val;
165
166         dev_rev_id_val = al_pcie_controller_readl(pcie, AXI_BASE_OFFSET +
167                                                   DEVICE_ID_OFFSET +
168                                                   DEVICE_REV_ID);
169         dev_id_val = FIELD_GET(DEVICE_REV_ID_DEV_ID_MASK, dev_rev_id_val);
170
171         switch (dev_id_val) {
172         case DEVICE_REV_ID_DEV_ID_X4:
173                 *rev_id = AL_PCIE_REV_ID_2;
174                 break;
175         case DEVICE_REV_ID_DEV_ID_X8:
176                 *rev_id = AL_PCIE_REV_ID_3;
177                 break;
178         case DEVICE_REV_ID_DEV_ID_X16:
179                 *rev_id = AL_PCIE_REV_ID_4;
180                 break;
181         default:
182                 dev_err(pcie->dev, "Unsupported dev_id_val (0x%x)\n",
183                         dev_id_val);
184                 return -EINVAL;
185         }
186
187         dev_dbg(pcie->dev, "dev_id_val: 0x%x\n", dev_id_val);
188
189         return 0;
190 }
191
192 static int al_pcie_reg_offsets_set(struct al_pcie *pcie)
193 {
194         switch (pcie->controller_rev_id) {
195         case AL_PCIE_REV_ID_2:
196                 pcie->reg_offsets.ob_ctrl = OB_CTRL_REV1_2_OFFSET;
197                 break;
198         case AL_PCIE_REV_ID_3:
199         case AL_PCIE_REV_ID_4:
200                 pcie->reg_offsets.ob_ctrl = OB_CTRL_REV3_5_OFFSET;
201                 break;
202         default:
203                 dev_err(pcie->dev, "Unsupported controller rev_id: 0x%x\n",
204                         pcie->controller_rev_id);
205                 return -EINVAL;
206         }
207
208         return 0;
209 }
210
211 static inline void al_pcie_target_bus_set(struct al_pcie *pcie,
212                                           u8 target_bus,
213                                           u8 mask_target_bus)
214 {
215         u32 reg;
216
217         reg = FIELD_PREP(CFG_TARGET_BUS_MASK_MASK, mask_target_bus) |
218               FIELD_PREP(CFG_TARGET_BUS_BUSNUM_MASK, target_bus);
219
220         al_pcie_controller_writel(pcie, AXI_BASE_OFFSET +
221                                   pcie->reg_offsets.ob_ctrl + CFG_TARGET_BUS,
222                                   reg);
223 }
224
225 static void __iomem *al_pcie_conf_addr_map(struct al_pcie *pcie,
226                                            unsigned int busnr,
227                                            unsigned int devfn)
228 {
229         struct al_pcie_target_bus_cfg *target_bus_cfg = &pcie->target_bus_cfg;
230         unsigned int busnr_ecam = busnr & target_bus_cfg->ecam_mask;
231         unsigned int busnr_reg = busnr & target_bus_cfg->reg_mask;
232         struct pcie_port *pp = &pcie->pci->pp;
233         void __iomem *pci_base_addr;
234
235         pci_base_addr = (void __iomem *)((uintptr_t)pp->va_cfg0_base +
236                                          (busnr_ecam << 20) +
237                                          PCIE_ECAM_DEVFN(devfn));
238
239         if (busnr_reg != target_bus_cfg->reg_val) {
240                 dev_dbg(pcie->pci->dev, "Changing target bus busnum val from 0x%x to 0x%x\n",
241                         target_bus_cfg->reg_val, busnr_reg);
242                 target_bus_cfg->reg_val = busnr_reg;
243                 al_pcie_target_bus_set(pcie,
244                                        target_bus_cfg->reg_val,
245                                        target_bus_cfg->reg_mask);
246         }
247
248         return pci_base_addr;
249 }
250
251 static int al_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
252                                  unsigned int devfn, int where, int size,
253                                  u32 *val)
254 {
255         struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
256         struct al_pcie *pcie = to_al_pcie(pci);
257         unsigned int busnr = bus->number;
258         void __iomem *pci_addr;
259         int rc;
260
261         pci_addr = al_pcie_conf_addr_map(pcie, busnr, devfn);
262
263         rc = dw_pcie_read(pci_addr + where, size, val);
264
265         dev_dbg(pci->dev, "%d-byte config read from %04x:%02x:%02x.%d offset 0x%x (pci_addr: 0x%px) - val:0x%x\n",
266                 size, pci_domain_nr(bus), bus->number,
267                 PCI_SLOT(devfn), PCI_FUNC(devfn), where,
268                 (pci_addr + where), *val);
269
270         return rc;
271 }
272
273 static int al_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
274                                  unsigned int devfn, int where, int size,
275                                  u32 val)
276 {
277         struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
278         struct al_pcie *pcie = to_al_pcie(pci);
279         unsigned int busnr = bus->number;
280         void __iomem *pci_addr;
281         int rc;
282
283         pci_addr = al_pcie_conf_addr_map(pcie, busnr, devfn);
284
285         rc = dw_pcie_write(pci_addr + where, size, val);
286
287         dev_dbg(pci->dev, "%d-byte config write to %04x:%02x:%02x.%d offset 0x%x (pci_addr: 0x%px) - val:0x%x\n",
288                 size, pci_domain_nr(bus), bus->number,
289                 PCI_SLOT(devfn), PCI_FUNC(devfn), where,
290                 (pci_addr + where), val);
291
292         return rc;
293 }
294
295 static void al_pcie_config_prepare(struct al_pcie *pcie)
296 {
297         struct al_pcie_target_bus_cfg *target_bus_cfg;
298         struct pcie_port *pp = &pcie->pci->pp;
299         unsigned int ecam_bus_mask;
300         u32 cfg_control_offset;
301         u8 subordinate_bus;
302         u8 secondary_bus;
303         u32 cfg_control;
304         u32 reg;
305
306         target_bus_cfg = &pcie->target_bus_cfg;
307
308         ecam_bus_mask = (pcie->ecam_size >> 20) - 1;
309         if (ecam_bus_mask > 255) {
310                 dev_warn(pcie->dev, "ECAM window size is larger than 256MB. Cutting off at 256\n");
311                 ecam_bus_mask = 255;
312         }
313
314         /* This portion is taken from the transaction address */
315         target_bus_cfg->ecam_mask = ecam_bus_mask;
316         /* This portion is taken from the cfg_target_bus reg */
317         target_bus_cfg->reg_mask = ~target_bus_cfg->ecam_mask;
318         target_bus_cfg->reg_val = pp->busn->start & target_bus_cfg->reg_mask;
319
320         al_pcie_target_bus_set(pcie, target_bus_cfg->reg_val,
321                                target_bus_cfg->reg_mask);
322
323         secondary_bus = pp->busn->start + 1;
324         subordinate_bus = pp->busn->end;
325
326         /* Set the valid values of secondary and subordinate buses */
327         cfg_control_offset = AXI_BASE_OFFSET + pcie->reg_offsets.ob_ctrl +
328                              CFG_CONTROL;
329
330         cfg_control = al_pcie_controller_readl(pcie, cfg_control_offset);
331
332         reg = cfg_control &
333               ~(CFG_CONTROL_SEC_BUS_MASK | CFG_CONTROL_SUBBUS_MASK);
334
335         reg |= FIELD_PREP(CFG_CONTROL_SUBBUS_MASK, subordinate_bus) |
336                FIELD_PREP(CFG_CONTROL_SEC_BUS_MASK, secondary_bus);
337
338         al_pcie_controller_writel(pcie, cfg_control_offset, reg);
339 }
340
341 static int al_pcie_host_init(struct pcie_port *pp)
342 {
343         struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
344         struct al_pcie *pcie = to_al_pcie(pci);
345         int rc;
346
347         rc = al_pcie_rev_id_get(pcie, &pcie->controller_rev_id);
348         if (rc)
349                 return rc;
350
351         rc = al_pcie_reg_offsets_set(pcie);
352         if (rc)
353                 return rc;
354
355         al_pcie_config_prepare(pcie);
356
357         return 0;
358 }
359
360 static const struct dw_pcie_host_ops al_pcie_host_ops = {
361         .rd_other_conf = al_pcie_rd_other_conf,
362         .wr_other_conf = al_pcie_wr_other_conf,
363         .host_init = al_pcie_host_init,
364 };
365
366 static int al_add_pcie_port(struct pcie_port *pp,
367                             struct platform_device *pdev)
368 {
369         struct device *dev = &pdev->dev;
370         int ret;
371
372         pp->ops = &al_pcie_host_ops;
373
374         ret = dw_pcie_host_init(pp);
375         if (ret) {
376                 dev_err(dev, "failed to initialize host\n");
377                 return ret;
378         }
379
380         return 0;
381 }
382
383 static const struct dw_pcie_ops dw_pcie_ops = {
384 };
385
386 static int al_pcie_probe(struct platform_device *pdev)
387 {
388         struct device *dev = &pdev->dev;
389         struct resource *controller_res;
390         struct resource *ecam_res;
391         struct resource *dbi_res;
392         struct al_pcie *al_pcie;
393         struct dw_pcie *pci;
394
395         al_pcie = devm_kzalloc(dev, sizeof(*al_pcie), GFP_KERNEL);
396         if (!al_pcie)
397                 return -ENOMEM;
398
399         pci = devm_kzalloc(dev, sizeof(*pci), GFP_KERNEL);
400         if (!pci)
401                 return -ENOMEM;
402
403         pci->dev = dev;
404         pci->ops = &dw_pcie_ops;
405
406         al_pcie->pci = pci;
407         al_pcie->dev = dev;
408
409         dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
410         pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res);
411         if (IS_ERR(pci->dbi_base)) {
412                 dev_err(dev, "couldn't remap dbi base %pR\n", dbi_res);
413                 return PTR_ERR(pci->dbi_base);
414         }
415
416         ecam_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
417         if (!ecam_res) {
418                 dev_err(dev, "couldn't find 'config' reg in DT\n");
419                 return -ENOENT;
420         }
421         al_pcie->ecam_size = resource_size(ecam_res);
422
423         controller_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
424                                                       "controller");
425         al_pcie->controller_base = devm_ioremap_resource(dev, controller_res);
426         if (IS_ERR(al_pcie->controller_base)) {
427                 dev_err(dev, "couldn't remap controller base %pR\n",
428                         controller_res);
429                 return PTR_ERR(al_pcie->controller_base);
430         }
431
432         dev_dbg(dev, "From DT: dbi_base: %pR, controller_base: %pR\n",
433                 dbi_res, controller_res);
434
435         platform_set_drvdata(pdev, al_pcie);
436
437         return al_add_pcie_port(&pci->pp, pdev);
438 }
439
440 static const struct of_device_id al_pcie_of_match[] = {
441         { .compatible = "amazon,al-alpine-v2-pcie",
442         },
443         { .compatible = "amazon,al-alpine-v3-pcie",
444         },
445         {},
446 };
447
448 static struct platform_driver al_pcie_driver = {
449         .driver = {
450                 .name   = "al-pcie",
451                 .of_match_table = al_pcie_of_match,
452                 .suppress_bind_attrs = true,
453         },
454         .probe = al_pcie_probe,
455 };
456 builtin_platform_driver(al_pcie_driver);
457
458 #endif /* CONFIG_PCIE_AL*/