1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2017 Cadence
3 // Cadence PCIe host controller driver.
4 // Author: Cyrille Pitchen <cyrille.pitchen@free-electrons.com>
6 #include <linux/kernel.h>
7 #include <linux/of_address.h>
8 #include <linux/of_pci.h>
9 #include <linux/platform_device.h>
10 #include <linux/pm_runtime.h>
12 #include "pcie-cadence.h"
15 * struct cdns_pcie_rc - private data for this PCIe Root Complex driver
16 * @pcie: Cadence PCIe controller
17 * @dev: pointer to PCIe device
18 * @cfg_res: start/end offsets in the physical system memory to map PCI
19 * configuration space accesses
20 * @bus_range: first/last buses behind the PCIe host controller
21 * @cfg_base: IO mapped window to access the PCI configuration space of a
22 * single function at a time
23 * @max_regions: maximum number of regions supported by the hardware
24 * @no_bar_nbits: Number of bits to keep for inbound (PCIe -> CPU) address
25 * translation (nbits sets into the "no BAR match" register)
26 * @vendor_id: PCI vendor ID
27 * @device_id: PCI device ID
30 struct cdns_pcie pcie
;
32 struct resource
*cfg_res
;
33 struct resource
*bus_range
;
34 void __iomem
*cfg_base
;
41 static void __iomem
*cdns_pci_map_bus(struct pci_bus
*bus
, unsigned int devfn
,
44 struct pci_host_bridge
*bridge
= pci_find_host_bridge(bus
);
45 struct cdns_pcie_rc
*rc
= pci_host_bridge_priv(bridge
);
46 struct cdns_pcie
*pcie
= &rc
->pcie
;
47 unsigned int busn
= bus
->number
;
50 if (busn
== rc
->bus_range
->start
) {
52 * Only the root port (devfn == 0) is connected to this bus.
53 * All other PCI devices are behind some bridge hence on another
59 return pcie
->reg_base
+ (where
& 0xfff);
61 /* Check that the link is up */
62 if (!(cdns_pcie_readl(pcie
, CDNS_PCIE_LM_BASE
) & 0x1))
64 /* Clear AXI link-down status */
65 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_LINKDOWN
, 0x0);
67 /* Update Output registers for AXI region 0. */
68 addr0
= CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(12) |
69 CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn
) |
70 CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(busn
);
71 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(0), addr0
);
73 /* Configuration Type 0 or Type 1 access. */
74 desc0
= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID
|
75 CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
77 * The bus number was already set once for all in desc1 by
78 * cdns_pcie_host_init_address_translation().
80 if (busn
== rc
->bus_range
->start
+ 1)
81 desc0
|= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0
;
83 desc0
|= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1
;
84 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_DESC0(0), desc0
);
86 return rc
->cfg_base
+ (where
& 0xfff);
89 static struct pci_ops cdns_pcie_host_ops
= {
90 .map_bus
= cdns_pci_map_bus
,
91 .read
= pci_generic_config_read
,
92 .write
= pci_generic_config_write
,
95 static const struct of_device_id cdns_pcie_host_of_match
[] = {
96 { .compatible
= "cdns,cdns-pcie-host" },
101 static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc
*rc
)
103 struct cdns_pcie
*pcie
= &rc
->pcie
;
107 * Set the root complex BAR configuration register:
108 * - disable both BAR0 and BAR1.
109 * - enable Prefetchable Memory Base and Limit registers in type 1
110 * config space (64 bits).
111 * - enable IO Base and Limit registers in type 1 config
114 ctrl
= CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED
;
115 value
= CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(ctrl
) |
116 CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(ctrl
) |
117 CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE
|
118 CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS
|
119 CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE
|
120 CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS
;
121 cdns_pcie_writel(pcie
, CDNS_PCIE_LM_RC_BAR_CFG
, value
);
123 /* Set root port configuration space */
124 if (rc
->vendor_id
!= 0xffff)
125 cdns_pcie_rp_writew(pcie
, PCI_VENDOR_ID
, rc
->vendor_id
);
126 if (rc
->device_id
!= 0xffff)
127 cdns_pcie_rp_writew(pcie
, PCI_DEVICE_ID
, rc
->device_id
);
129 cdns_pcie_rp_writeb(pcie
, PCI_CLASS_REVISION
, 0);
130 cdns_pcie_rp_writeb(pcie
, PCI_CLASS_PROG
, 0);
131 cdns_pcie_rp_writew(pcie
, PCI_CLASS_DEVICE
, PCI_CLASS_BRIDGE_PCI
);
136 static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc
*rc
)
138 struct cdns_pcie
*pcie
= &rc
->pcie
;
139 struct resource
*cfg_res
= rc
->cfg_res
;
140 struct resource
*mem_res
= pcie
->mem_res
;
141 struct resource
*bus_range
= rc
->bus_range
;
142 struct device
*dev
= rc
->dev
;
143 struct device_node
*np
= dev
->of_node
;
144 struct of_pci_range_parser parser
;
145 struct of_pci_range range
;
146 u32 addr0
, addr1
, desc1
;
151 * Reserve region 0 for PCI configure space accesses:
152 * OB_REGION_PCI_ADDR0 and OB_REGION_DESC0 are updated dynamically by
153 * cdns_pci_map_bus(), other region registers are set here once for all.
155 addr1
= 0; /* Should be programmed to zero. */
156 desc1
= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus_range
->start
);
157 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1
);
158 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1
);
160 cpu_addr
= cfg_res
->start
- mem_res
->start
;
161 addr0
= CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(12) |
162 (lower_32_bits(cpu_addr
) & GENMASK(31, 8));
163 addr1
= upper_32_bits(cpu_addr
);
164 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(0), addr0
);
165 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(0), addr1
);
167 err
= of_pci_range_parser_init(&parser
, np
);
172 for_each_of_pci_range(&parser
, &range
) {
175 if (r
>= rc
->max_regions
)
178 if ((range
.flags
& IORESOURCE_TYPE_BITS
) == IORESOURCE_MEM
)
180 else if ((range
.flags
& IORESOURCE_TYPE_BITS
) == IORESOURCE_IO
)
185 cdns_pcie_set_outbound_region(pcie
, 0, r
, is_io
,
193 * Set Root Port no BAR match Inbound Translation registers:
194 * needed for MSI and DMA.
195 * Root Port BAR0 and BAR1 are disabled, hence no need to set their
196 * inbound translation registers.
198 addr0
= CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(rc
->no_bar_nbits
);
200 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_IB_RP_BAR_ADDR0(RP_NO_BAR
), addr0
);
201 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_IB_RP_BAR_ADDR1(RP_NO_BAR
), addr1
);
206 static int cdns_pcie_host_init(struct device
*dev
,
207 struct list_head
*resources
,
208 struct cdns_pcie_rc
*rc
)
210 struct resource
*bus_range
= NULL
;
213 /* Parse our PCI ranges and request their resources */
214 err
= pci_parse_request_of_pci_ranges(dev
, resources
, &bus_range
);
218 rc
->bus_range
= bus_range
;
219 rc
->pcie
.bus
= bus_range
->start
;
221 err
= cdns_pcie_host_init_root_port(rc
);
225 err
= cdns_pcie_host_init_address_translation(rc
);
232 pci_free_resource_list(resources
);
236 static int cdns_pcie_host_probe(struct platform_device
*pdev
)
239 struct device
*dev
= &pdev
->dev
;
240 struct device_node
*np
= dev
->of_node
;
241 struct pci_host_bridge
*bridge
;
242 struct list_head resources
;
243 struct cdns_pcie_rc
*rc
;
244 struct cdns_pcie
*pcie
;
245 struct resource
*res
;
249 bridge
= devm_pci_alloc_host_bridge(dev
, sizeof(*rc
));
253 rc
= pci_host_bridge_priv(bridge
);
259 rc
->max_regions
= 32;
260 of_property_read_u32(np
, "cdns,max-outbound-regions", &rc
->max_regions
);
262 rc
->no_bar_nbits
= 32;
263 of_property_read_u32(np
, "cdns,no-bar-match-nbits", &rc
->no_bar_nbits
);
265 rc
->vendor_id
= 0xffff;
266 of_property_read_u16(np
, "vendor-id", &rc
->vendor_id
);
268 rc
->device_id
= 0xffff;
269 of_property_read_u16(np
, "device-id", &rc
->device_id
);
271 type
= of_get_property(np
, "device_type", NULL
);
272 if (!type
|| strcmp(type
, "pci")) {
273 dev_err(dev
, "invalid \"device_type\" %s\n", type
);
277 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "reg");
278 pcie
->reg_base
= devm_ioremap_resource(dev
, res
);
279 if (IS_ERR(pcie
->reg_base
)) {
280 dev_err(dev
, "missing \"reg\"\n");
281 return PTR_ERR(pcie
->reg_base
);
284 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "cfg");
285 rc
->cfg_base
= devm_pci_remap_cfg_resource(dev
, res
);
286 if (IS_ERR(rc
->cfg_base
)) {
287 dev_err(dev
, "missing \"cfg\"\n");
288 return PTR_ERR(rc
->cfg_base
);
292 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "mem");
294 dev_err(dev
, "missing \"mem\"\n");
299 ret
= cdns_pcie_init_phy(dev
, pcie
);
301 dev_err(dev
, "failed to init phy\n");
304 platform_set_drvdata(pdev
, pcie
);
306 pm_runtime_enable(dev
);
307 ret
= pm_runtime_get_sync(dev
);
309 dev_err(dev
, "pm_runtime_get_sync() failed\n");
313 ret
= cdns_pcie_host_init(dev
, &resources
, rc
);
317 list_splice_init(&resources
, &bridge
->windows
);
318 bridge
->dev
.parent
= dev
;
319 bridge
->busnr
= pcie
->bus
;
320 bridge
->ops
= &cdns_pcie_host_ops
;
321 bridge
->map_irq
= of_irq_parse_and_map_pci
;
322 bridge
->swizzle_irq
= pci_common_swizzle
;
324 ret
= pci_host_probe(bridge
);
331 pci_free_resource_list(&resources
);
334 pm_runtime_put_sync(dev
);
337 pm_runtime_disable(dev
);
338 cdns_pcie_disable_phy(pcie
);
339 phy_count
= pcie
->phy_count
;
341 device_link_del(pcie
->link
[phy_count
]);
346 static void cdns_pcie_shutdown(struct platform_device
*pdev
)
348 struct device
*dev
= &pdev
->dev
;
349 struct cdns_pcie
*pcie
= dev_get_drvdata(dev
);
352 ret
= pm_runtime_put_sync(dev
);
354 dev_dbg(dev
, "pm_runtime_put_sync failed\n");
356 pm_runtime_disable(dev
);
357 cdns_pcie_disable_phy(pcie
);
360 static struct platform_driver cdns_pcie_host_driver
= {
362 .name
= "cdns-pcie-host",
363 .of_match_table
= cdns_pcie_host_of_match
,
364 .pm
= &cdns_pcie_pm_ops
,
366 .probe
= cdns_pcie_host_probe
,
367 .shutdown
= cdns_pcie_shutdown
,
369 builtin_platform_driver(cdns_pcie_host_driver
);