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"
14 static void __iomem
*cdns_pci_map_bus(struct pci_bus
*bus
, unsigned int devfn
,
17 struct pci_host_bridge
*bridge
= pci_find_host_bridge(bus
);
18 struct cdns_pcie_rc
*rc
= pci_host_bridge_priv(bridge
);
19 struct cdns_pcie
*pcie
= &rc
->pcie
;
20 unsigned int busn
= bus
->number
;
23 if (busn
== rc
->bus_range
->start
) {
25 * Only the root port (devfn == 0) is connected to this bus.
26 * All other PCI devices are behind some bridge hence on another
32 return pcie
->reg_base
+ (where
& 0xfff);
34 /* Check that the link is up */
35 if (!(cdns_pcie_readl(pcie
, CDNS_PCIE_LM_BASE
) & 0x1))
37 /* Clear AXI link-down status */
38 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_LINKDOWN
, 0x0);
40 /* Update Output registers for AXI region 0. */
41 addr0
= CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_NBITS(12) |
42 CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_DEVFN(devfn
) |
43 CDNS_PCIE_AT_OB_REGION_PCI_ADDR0_BUS(busn
);
44 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_PCI_ADDR0(0), addr0
);
46 /* Configuration Type 0 or Type 1 access. */
47 desc0
= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID
|
48 CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
50 * The bus number was already set once for all in desc1 by
51 * cdns_pcie_host_init_address_translation().
53 if (busn
== rc
->bus_range
->start
+ 1)
54 desc0
|= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0
;
56 desc0
|= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1
;
57 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_DESC0(0), desc0
);
59 return rc
->cfg_base
+ (where
& 0xfff);
62 static struct pci_ops cdns_pcie_host_ops
= {
63 .map_bus
= cdns_pci_map_bus
,
64 .read
= pci_generic_config_read
,
65 .write
= pci_generic_config_write
,
69 static int cdns_pcie_host_init_root_port(struct cdns_pcie_rc
*rc
)
71 struct cdns_pcie
*pcie
= &rc
->pcie
;
75 * Set the root complex BAR configuration register:
76 * - disable both BAR0 and BAR1.
77 * - enable Prefetchable Memory Base and Limit registers in type 1
78 * config space (64 bits).
79 * - enable IO Base and Limit registers in type 1 config
82 ctrl
= CDNS_PCIE_LM_BAR_CFG_CTRL_DISABLED
;
83 value
= CDNS_PCIE_LM_RC_BAR_CFG_BAR0_CTRL(ctrl
) |
84 CDNS_PCIE_LM_RC_BAR_CFG_BAR1_CTRL(ctrl
) |
85 CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_ENABLE
|
86 CDNS_PCIE_LM_RC_BAR_CFG_PREFETCH_MEM_64BITS
|
87 CDNS_PCIE_LM_RC_BAR_CFG_IO_ENABLE
|
88 CDNS_PCIE_LM_RC_BAR_CFG_IO_32BITS
;
89 cdns_pcie_writel(pcie
, CDNS_PCIE_LM_RC_BAR_CFG
, value
);
91 /* Set root port configuration space */
92 if (rc
->vendor_id
!= 0xffff)
93 cdns_pcie_rp_writew(pcie
, PCI_VENDOR_ID
, rc
->vendor_id
);
94 if (rc
->device_id
!= 0xffff)
95 cdns_pcie_rp_writew(pcie
, PCI_DEVICE_ID
, rc
->device_id
);
97 cdns_pcie_rp_writeb(pcie
, PCI_CLASS_REVISION
, 0);
98 cdns_pcie_rp_writeb(pcie
, PCI_CLASS_PROG
, 0);
99 cdns_pcie_rp_writew(pcie
, PCI_CLASS_DEVICE
, PCI_CLASS_BRIDGE_PCI
);
104 static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc
*rc
)
106 struct cdns_pcie
*pcie
= &rc
->pcie
;
107 struct resource
*mem_res
= pcie
->mem_res
;
108 struct resource
*bus_range
= rc
->bus_range
;
109 struct resource
*cfg_res
= rc
->cfg_res
;
110 struct device
*dev
= pcie
->dev
;
111 struct device_node
*np
= dev
->of_node
;
112 struct of_pci_range_parser parser
;
113 struct of_pci_range range
;
114 u32 addr0
, addr1
, desc1
;
119 * Reserve region 0 for PCI configure space accesses:
120 * OB_REGION_PCI_ADDR0 and OB_REGION_DESC0 are updated dynamically by
121 * cdns_pci_map_bus(), other region registers are set here once for all.
123 addr1
= 0; /* Should be programmed to zero. */
124 desc1
= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus_range
->start
);
125 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1
);
126 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1
);
128 cpu_addr
= cfg_res
->start
- mem_res
->start
;
129 addr0
= CDNS_PCIE_AT_OB_REGION_CPU_ADDR0_NBITS(12) |
130 (lower_32_bits(cpu_addr
) & GENMASK(31, 8));
131 addr1
= upper_32_bits(cpu_addr
);
132 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(0), addr0
);
133 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(0), addr1
);
135 err
= of_pci_range_parser_init(&parser
, np
);
140 for_each_of_pci_range(&parser
, &range
) {
143 if (r
>= rc
->max_regions
)
146 if ((range
.flags
& IORESOURCE_TYPE_BITS
) == IORESOURCE_MEM
)
148 else if ((range
.flags
& IORESOURCE_TYPE_BITS
) == IORESOURCE_IO
)
153 cdns_pcie_set_outbound_region(pcie
, 0, r
, is_io
,
161 * Set Root Port no BAR match Inbound Translation registers:
162 * needed for MSI and DMA.
163 * Root Port BAR0 and BAR1 are disabled, hence no need to set their
164 * inbound translation registers.
166 addr0
= CDNS_PCIE_AT_IB_RP_BAR_ADDR0_NBITS(rc
->no_bar_nbits
);
168 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_IB_RP_BAR_ADDR0(RP_NO_BAR
), addr0
);
169 cdns_pcie_writel(pcie
, CDNS_PCIE_AT_IB_RP_BAR_ADDR1(RP_NO_BAR
), addr1
);
174 static int cdns_pcie_host_init(struct device
*dev
,
175 struct list_head
*resources
,
176 struct cdns_pcie_rc
*rc
)
178 struct resource
*bus_range
= NULL
;
181 /* Parse our PCI ranges and request their resources */
182 err
= pci_parse_request_of_pci_ranges(dev
, resources
, NULL
, &bus_range
);
186 rc
->bus_range
= bus_range
;
187 rc
->pcie
.bus
= bus_range
->start
;
189 err
= cdns_pcie_host_init_root_port(rc
);
193 err
= cdns_pcie_host_init_address_translation(rc
);
200 pci_free_resource_list(resources
);
204 int cdns_pcie_host_setup(struct cdns_pcie_rc
*rc
)
206 struct device
*dev
= rc
->pcie
.dev
;
207 struct platform_device
*pdev
= to_platform_device(dev
);
208 struct device_node
*np
= dev
->of_node
;
209 struct pci_host_bridge
*bridge
;
210 struct list_head resources
;
211 struct cdns_pcie
*pcie
;
212 struct resource
*res
;
215 bridge
= pci_host_bridge_from_priv(rc
);
222 rc
->max_regions
= 32;
223 of_property_read_u32(np
, "cdns,max-outbound-regions", &rc
->max_regions
);
225 rc
->no_bar_nbits
= 32;
226 of_property_read_u32(np
, "cdns,no-bar-match-nbits", &rc
->no_bar_nbits
);
228 rc
->vendor_id
= 0xffff;
229 of_property_read_u16(np
, "vendor-id", &rc
->vendor_id
);
231 rc
->device_id
= 0xffff;
232 of_property_read_u16(np
, "device-id", &rc
->device_id
);
234 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "reg");
235 pcie
->reg_base
= devm_ioremap_resource(dev
, res
);
236 if (IS_ERR(pcie
->reg_base
)) {
237 dev_err(dev
, "missing \"reg\"\n");
238 return PTR_ERR(pcie
->reg_base
);
241 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "cfg");
242 rc
->cfg_base
= devm_pci_remap_cfg_resource(dev
, res
);
243 if (IS_ERR(rc
->cfg_base
)) {
244 dev_err(dev
, "missing \"cfg\"\n");
245 return PTR_ERR(rc
->cfg_base
);
249 res
= platform_get_resource_byname(pdev
, IORESOURCE_MEM
, "mem");
251 dev_err(dev
, "missing \"mem\"\n");
257 ret
= cdns_pcie_host_init(dev
, &resources
, rc
);
261 list_splice_init(&resources
, &bridge
->windows
);
262 bridge
->dev
.parent
= dev
;
263 bridge
->busnr
= pcie
->bus
;
264 bridge
->ops
= &cdns_pcie_host_ops
;
265 bridge
->map_irq
= of_irq_parse_and_map_pci
;
266 bridge
->swizzle_irq
= pci_common_swizzle
;
268 ret
= pci_host_probe(bridge
);
275 pci_free_resource_list(&resources
);
278 pm_runtime_put_sync(dev
);