1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <libpayload.h>
7 * iATU Unroll-specific register definitions
9 #define PCIE_ATU_UNR_REGION_CTRL1 0x00
10 #define PCIE_ATU_UNR_REGION_CTRL2 0x04
11 #define PCIE_ATU_UNR_LOWER_BASE 0x08
12 #define PCIE_ATU_UNR_UPPER_BASE 0x0C
13 #define PCIE_ATU_UNR_LIMIT 0x10
14 #define PCIE_ATU_UNR_LOWER_TARGET 0x14
15 #define PCIE_ATU_UNR_UPPER_TARGET 0x18
16 #define PCIE_ATU_REGION_INDEX0 0x0
17 #define PCIE_ATU_TYPE_CFG0 0x4
18 #define PCIE_ATU_TYPE_CFG1 0x5
19 #define PCIE_ATU_ENABLE BIT(31)
20 #define ATU_CTRL2 PCIE_ATU_UNR_REGION_CTRL2
21 #define ATU_ENABLE PCIE_ATU_ENABLE
23 #define PCIE_ATU_BUS(x) (((x) & 0xff) << 24)
24 #define PCIE_ATU_DEV(x) (((x) & 0x1f) << 19)
25 #define PCIE_ATU_FUNC(x) (((x) & 0x7) << 16)
26 #define LINK_WAIT_IATU_US 1000
27 #define LINK_WAIT_MAX_IATU_RETRIES 5
29 /* Register address builder */
30 #define PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(region) ((region) << 9)
32 #define lower_32_bits(n) ((u32)(n))
33 #define upper_32_bits(n) ((u32)(((n) >> 16) >> 16))
36 * ATU & endpoint config space base address offsets relative to
37 * PCIe controller base address.
39 #define QCOM_ATU_BASE_OFFSET 0x1000
40 #define QCOM_EP_CFG_OFFSET 0x100000
41 #define QCOM_EP_CFG_SIZE 0x1000 /* 4K */
43 static void dw_pcie_writel_iatu(void *atu_base
, unsigned short index
,
44 uint32_t reg
, uint32_t val
)
46 uint32_t offset
= PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index
);
48 write32(atu_base
+ offset
+ reg
, val
);
51 static uint32_t dw_pcie_readl_iatu(void *atu_base
, unsigned short index
,
54 uint32_t offset
= PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index
);
56 return read32(atu_base
+ offset
+ reg
);
59 static void dw_pcie_prog_outbound_atu(void *atu_base
, unsigned short index
,
60 unsigned int type
, uint64_t cfg_addr
,
61 uint64_t pcie_addr
, uint32_t cfg_size
)
63 dw_pcie_writel_iatu(atu_base
, index
, PCIE_ATU_UNR_LOWER_BASE
,
64 lower_32_bits(cfg_addr
));
65 dw_pcie_writel_iatu(atu_base
, index
, PCIE_ATU_UNR_UPPER_BASE
,
66 upper_32_bits(cfg_addr
));
67 dw_pcie_writel_iatu(atu_base
, index
, PCIE_ATU_UNR_LIMIT
,
68 lower_32_bits(cfg_addr
+ cfg_size
- 1));
69 dw_pcie_writel_iatu(atu_base
, index
, PCIE_ATU_UNR_LOWER_TARGET
,
70 lower_32_bits(pcie_addr
));
71 dw_pcie_writel_iatu(atu_base
, index
, PCIE_ATU_UNR_UPPER_TARGET
,
72 upper_32_bits(pcie_addr
));
73 dw_pcie_writel_iatu(atu_base
, index
, PCIE_ATU_UNR_REGION_CTRL1
, type
);
74 dw_pcie_writel_iatu(atu_base
, index
, PCIE_ATU_UNR_REGION_CTRL2
,
77 * Make sure ATU enable takes effect before any subsequent config
80 if (retry(LINK_WAIT_MAX_IATU_RETRIES
,
81 (dw_pcie_readl_iatu(atu_base
, index
, ATU_CTRL2
) & ATU_ENABLE
),
82 udelay(LINK_WAIT_IATU_US
)))
85 printf("outbound iATU is couldn't be enabled after 5ms\n");
88 /* Get PCIe MMIO configuration space base address */
89 uintptr_t pci_map_bus(pcidev_t dev
)
91 unsigned int atu_type
, busdev
;
93 void *cntrlr_base
, *config_base
, *atu_base
;
94 unsigned int current_bus
= PCI_BUS(dev
);
95 unsigned int devfn
= (PCI_SLOT(dev
) << 3) | PCI_FUNC(dev
);
96 static pcidev_t current_dev
;
99 * Extract PCIe controller base from coreboot and derive the ATU and
100 * endpoint config base addresses from it.
102 cntrlr_base
= (void *)lib_sysinfo
.pcie_ctrl_base
;
103 config_base
= (void *)cntrlr_base
+ QCOM_EP_CFG_OFFSET
;
104 config_size
= (uint32_t)QCOM_EP_CFG_SIZE
;
105 atu_base
= (void *)cntrlr_base
+ QCOM_ATU_BASE_OFFSET
;
108 * Cache the dev. For same dev, ATU mapping is not needed for each
111 if (current_dev
== dev
)
116 busdev
= PCIE_ATU_BUS(current_bus
) |
117 PCIE_ATU_DEV(PCI_SLOT(dev
)) |
118 PCIE_ATU_FUNC(PCI_FUNC(dev
));
120 atu_type
= current_bus
== 1 ? PCIE_ATU_TYPE_CFG0
: PCIE_ATU_TYPE_CFG1
;
122 dw_pcie_prog_outbound_atu(atu_base
, PCIE_ATU_REGION_INDEX0
, atu_type
,
123 (uint64_t)config_base
, busdev
, config_size
);
125 return (uintptr_t)config_base
+ (QCOM_EP_CFG_SIZE
* devfn
);