soc/intel/xeon_sp: Allow OS to control LTR and AER
[coreboot2.git] / src / soc / mediatek / common / pcie.c
blob9269fbd7d38c9f65a02c63afbf3fd951e6ab87ae
1 /* SPDX-License-Identifier: GPL-2.0-only */
3 #include <boot/coreboot_tables.h>
4 #include <console/console.h>
5 #include <device/device.h>
6 #include <device/mmio.h>
7 #include <device/pci.h>
8 #include <device/pci_ids.h>
9 #include <delay.h>
10 #include <lib.h>
11 #include <soc/addressmap.h>
12 #include <soc/early_init.h>
13 #include <soc/pcie.h>
14 #include <soc/pcie_common.h>
15 #include <soc/soc_chip.h>
16 #include <types.h>
18 #define PCIE_SETTING_REG 0x80
19 #define PCIE_PCI_IDS_1 0x9c
20 #define PCI_CLASS(class) ((class) << 8)
21 #define PCIE_RC_MODE BIT(0)
23 #define PCIE_CFGNUM_REG 0x140
24 #define PCIE_CFG_DEVFN(devfn) ((devfn) & GENMASK(7, 0))
25 #define PCIE_CFG_BUS(bus) (((bus) << 8) & GENMASK(15, 8))
26 #define PCIE_CFG_OFFSET_ADDR 0x1000
27 #define PCIE_CFG_HEADER(bus, devfn) \
28 (PCIE_CFG_BUS(bus) | PCIE_CFG_DEVFN(devfn))
30 #define PCIE_RST_CTRL_REG 0x148
31 #define PCIE_MAC_RSTB BIT(0)
32 #define PCIE_PHY_RSTB BIT(1)
33 #define PCIE_BRG_RSTB BIT(2)
34 #define PCIE_PE_RSTB BIT(3)
36 #define PCIE_LTSSM_STATUS_REG 0x150
37 #define PCIE_LTSSM_STATE(val) (((val) >> 24) & 0x1f)
39 #define PCIE_LINK_STATUS_REG 0x154
40 #define PCIE_CTRL_LINKUP BIT(8)
42 #define PCI_NUM_INTX 4
43 #define PCIE_INT_ENABLE_REG 0x180
44 #define PCIE_INTX_SHIFT 24
45 #define PCIE_INTX_ENABLE \
46 GENMASK(PCIE_INTX_SHIFT + PCI_NUM_INTX - 1, PCIE_INTX_SHIFT)
48 #define PCIE_TRANS_TABLE_BASE_REG 0x800
49 #define PCIE_ATR_SRC_ADDR_MSB_OFFSET 0x4
50 #define PCIE_ATR_TRSL_ADDR_LSB_OFFSET 0x8
51 #define PCIE_ATR_TRSL_ADDR_MSB_OFFSET 0xc
52 #define PCIE_ATR_TRSL_PARAM_OFFSET 0x10
53 #define PCIE_ATR_TLB_SET_OFFSET 0x20
55 #define PCIE_MAX_TRANS_TABLES 8
56 #define PCIE_ATR_EN BIT(0)
57 #define PCIE_ATR_SIZE(size) \
58 (((((size) - 1) << 1) & GENMASK(6, 1)) | PCIE_ATR_EN)
59 #define PCIE_ATR_ID(id) ((id) & GENMASK(3, 0))
60 #define PCIE_ATR_TYPE_MEM PCIE_ATR_ID(0)
61 #define PCIE_ATR_TYPE_IO PCIE_ATR_ID(1)
62 #define PCIE_ATR_TLP_TYPE(type) (((type) << 16) & GENMASK(18, 16))
63 #define PCIE_ATR_TLP_TYPE_MEM PCIE_ATR_TLP_TYPE(0)
64 #define PCIE_ATR_TLP_TYPE_IO PCIE_ATR_TLP_TYPE(2)
66 /* LTSSM state in PCIE_LTSSM_STATUS_REG bit[28:24] */
67 static const char *const ltssm_str[] = {
68 "detect.quiet", /* 0x00 */
69 "detect.active", /* 0x01 */
70 "polling.active", /* 0x02 */
71 "polling.compliance", /* 0x03 */
72 "polling.configuration", /* 0x04 */
73 "config.linkwidthstart", /* 0x05 */
74 "config.linkwidthaccept", /* 0x06 */
75 "config.lanenumwait", /* 0x07 */
76 "config.lanenumaccept", /* 0x08 */
77 "config.complete", /* 0x09 */
78 "config.idle", /* 0x0A */
79 "recovery.receiverlock", /* 0x0B */
80 "recovery.equalization", /* 0x0C */
81 "recovery.speed", /* 0x0D */
82 "recovery.receiverconfig", /* 0x0E */
83 "recovery.idle", /* 0x0F */
84 "L0", /* 0x10 */
85 "L0s", /* 0x11 */
86 "L1.entry", /* 0x12 */
87 "L1.idle", /* 0x13 */
88 "L2.idle", /* 0x14 */
89 "L2.transmitwake", /* 0x15 */
90 "disable", /* 0x16 */
91 "loopback.entry", /* 0x17 */
92 "loopback.active", /* 0x18 */
93 "loopback.exit", /* 0x19 */
94 "hotreset", /* 0x1A */
97 static uintptr_t mtk_pcie_get_controller_base(pci_devfn_t devfn)
99 DEVTREE_CONST struct device *root_dev;
100 const mtk_soc_config_t *config;
101 static uintptr_t base = 0;
103 if (!base) {
104 root_dev = pcidev_path_on_root(devfn);
105 config = config_of(root_dev);
106 base = config->pcie_config.base;
109 return base;
112 volatile union pci_bank *pci_map_bus(pci_devfn_t dev)
114 u32 val, devfn, bus;
115 uintptr_t base;
117 devfn = PCI_DEV2DEVFN(dev);
118 bus = PCI_DEV2SEGBUS(dev);
119 val = PCIE_CFG_HEADER(bus, devfn);
121 base = mtk_pcie_get_controller_base(dev);
122 write32p(base + PCIE_CFGNUM_REG, val);
124 return (void *)(base + PCIE_CFG_OFFSET_ADDR);
127 static void mtk_pcie_set_table(uintptr_t table, uint32_t cpu_addr,
128 uint32_t pci_addr, uint32_t size, uint32_t attr)
130 write32p(table, cpu_addr | PCIE_ATR_SIZE(__fls(size)));
131 write32p(table + PCIE_ATR_SRC_ADDR_MSB_OFFSET, 0);
132 write32p(table + PCIE_ATR_TRSL_ADDR_LSB_OFFSET, pci_addr);
133 write32p(table + PCIE_ATR_TRSL_ADDR_MSB_OFFSET, 0);
134 write32p(table + PCIE_ATR_TRSL_PARAM_OFFSET, attr);
137 static int mtk_pcie_set_trans_window(size_t *count, uintptr_t table_base,
138 const struct mtk_pcie_mmio_res *mmio_res)
140 const char *range_type;
141 uintptr_t table;
142 uint32_t table_attr;
143 uint32_t cpu_addr, pci_addr, remaining, size;
145 if (!mmio_res)
146 return -1;
148 if (mmio_res->type == IORESOURCE_IO) {
149 range_type = "IO";
150 table_attr = PCIE_ATR_TYPE_IO | PCIE_ATR_TLP_TYPE_IO;
151 } else if (mmio_res->type == IORESOURCE_MEM) {
152 range_type = "MEM";
153 table_attr = PCIE_ATR_TYPE_MEM | PCIE_ATR_TLP_TYPE_MEM;
154 } else {
155 printk(BIOS_ERR, "%s: Unknown trans table type %#lx\n",
156 __func__, mmio_res->type);
157 return -1;
160 cpu_addr = mmio_res->cpu_addr;
161 pci_addr = mmio_res->pci_addr;
162 remaining = mmio_res->size;
164 while (remaining && *count < PCIE_MAX_TRANS_TABLES) {
166 * The table size needs to be a power of 2.
167 * In addition, cpu_addr needs to be aligned to the size.
169 size = BIT(__fls(remaining));
171 if (cpu_addr > 0)
172 size = MIN(size, BIT(__ffs(cpu_addr)));
174 /* Minimum size of translate table is 4KiB */
175 if (size < 4 * KiB) {
176 printk(BIOS_ERR, "%s: table size %#x is less than 4KiB\n",
177 __func__, size);
178 return -1;
181 table = table_base + *count * PCIE_ATR_TLB_SET_OFFSET;
182 mtk_pcie_set_table(table, cpu_addr, pci_addr, size, table_attr);
184 printk(BIOS_INFO,
185 "%s: set %s trans window: cpu_addr = %#x, pci_addr = %#x, size = %#x\n",
186 __func__, range_type, cpu_addr, pci_addr, size);
187 cpu_addr += size;
188 pci_addr += size;
189 remaining -= size;
190 (*count)++;
193 if (remaining) {
194 printk(BIOS_ERR, "%s: Not enough translation windows, remaining size: %#x\n",
195 __func__, remaining);
196 return -1;
199 return 0;
202 static void mtk_pcie_domain_new_res(struct device *dev, unsigned int index,
203 const struct mtk_pcie_mmio_res *mmio_res)
205 struct resource *res;
207 if (!mmio_res)
208 return;
210 res = new_resource(dev, index);
211 res->base = mmio_res->cpu_addr;
212 res->limit = mmio_res->cpu_addr + mmio_res->size - 1;
213 res->flags = mmio_res->type | IORESOURCE_SUBTRACTIVE |
214 IORESOURCE_ASSIGNED;
217 void mtk_pcie_domain_read_resources(struct device *dev)
219 const mtk_soc_config_t *config = config_of(dev);
220 const struct mtk_pcie_config *conf = &config->pcie_config;
222 mtk_pcie_domain_new_res(dev, IOINDEX_SUBTRACTIVE(0, 0),
223 &conf->mmio_res_io);
225 mtk_pcie_domain_new_res(dev, IOINDEX_SUBTRACTIVE(1, 0),
226 &conf->mmio_res_mem);
229 void mtk_pcie_domain_set_resources(struct device *dev)
231 const mtk_soc_config_t *config = config_of(dev);
232 const struct mtk_pcie_config *conf = &config->pcie_config;
233 uintptr_t table_base = conf->base + PCIE_TRANS_TABLE_BASE_REG;
234 size_t count = 0;
236 /* Initialize I/O space constraints. */
237 if (mtk_pcie_set_trans_window(&count, table_base, &conf->mmio_res_io) < 0) {
238 printk(BIOS_ERR, "%s: Failed to set IO window, ignore it\n",
239 __func__);
240 count = 0;
243 /* Initialize memory resources constraints. */
244 if (mtk_pcie_set_trans_window(&count, table_base, &conf->mmio_res_mem) < 0)
245 printk(BIOS_ERR, "%s: Failed to set MEM window\n", __func__);
247 pci_domain_set_resources(dev);
250 void mtk_pcie_reset(uintptr_t base_reg, bool enable)
252 uint32_t flags = PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB;
254 if (enable)
255 setbits32p(base_reg + PCIE_RST_CTRL_REG, flags);
256 else
257 clrbits32p(base_reg + PCIE_RST_CTRL_REG, flags);
260 enum cb_err fill_lb_pcie(struct lb_pcie *pcie)
262 if (!pci_root_bus())
263 return CB_ERR;
265 pcie->ctrl_base = mtk_pcie_get_controller_base(0);
266 return CB_SUCCESS;
269 static void wait_perst_asserted(uintptr_t base)
271 long perst_time_us;
273 perst_time_us = early_init_get_elapsed_time_us(EARLY_INIT_PCIE);
274 printk(BIOS_DEBUG, "%s: %ld us elapsed since assert PERST#\n",
275 __func__, perst_time_us);
278 * Described in PCIe CEM specification sections 2.2
279 * (PERST# Signal) and 2.2.1 (Initial Power-Up (G3 to S0)).
280 * The deassertion of PERST# should be delayed 100ms (TPVPERL)
281 * for the power and clock to become stable.
283 const long min_perst_time_us = 100000; /* 100 ms */
284 if (perst_time_us < min_perst_time_us) {
285 if (!perst_time_us) {
286 printk(BIOS_WARNING,
287 "%s: PCIe early init data not found, sleeping 100ms\n",
288 __func__);
289 mtk_pcie_reset(base, true);
290 } else {
291 printk(BIOS_WARNING,
292 "%s: Need an extra %ld us delay to meet PERST# deassertion requirement\n",
293 __func__, min_perst_time_us - perst_time_us);
296 udelay(min_perst_time_us - perst_time_us);
300 static void deassert_perst(uintptr_t base)
302 /* Set as RC mode */
303 setbits32p(base + PCIE_SETTING_REG, PCIE_RC_MODE);
305 /* Set class code */
306 clrsetbits32p(base + PCIE_PCI_IDS_1, GENMASK(31, 8),
307 PCI_CLASS(PCI_CLASS_BRIDGE_PCI << 8));
309 /* Mask all INTx interrupts */
310 clrbits32p(base + PCIE_INT_ENABLE_REG, PCIE_INTX_ENABLE);
312 /* Above registers must be set before de-asserting PERST# */
313 /* De-assert reset signals */
314 mtk_pcie_reset(base, false);
317 static void wait_perst_done(uintptr_t base)
319 long perst_time_us;
321 wait_perst_asserted(base);
323 perst_time_us = early_init_get_elapsed_time_us(EARLY_INIT_PCIE_RESET);
324 printk(BIOS_DEBUG, "%s: %ld us elapsed since de-assert PERST#\n",
325 __func__, perst_time_us);
327 if (!perst_time_us) {
328 printk(BIOS_INFO, "%s: PCIe early PERST# de-assertion is not done, "
329 "de-assert PERST# now\n", __func__);
330 deassert_perst(base);
334 void mtk_pcie_deassert_perst(void)
336 uintptr_t base = mtk_pcie_get_controller_base(0);
338 wait_perst_done(base);
339 early_init_save_time(EARLY_INIT_PCIE_RESET);
342 void mtk_pcie_domain_enable(struct device *dev)
344 const mtk_soc_config_t *config = config_of(dev);
345 const struct mtk_pcie_config *conf = &config->pcie_config;
346 const char *ltssm_state;
347 size_t tries = 0;
348 uint32_t val;
350 wait_perst_done(conf->base);
352 if (!retry(100,
353 (tries++, read32p(conf->base + PCIE_LINK_STATUS_REG) &
354 PCIE_CTRL_LINKUP), mdelay(1))) {
355 val = read32p(conf->base + PCIE_LTSSM_STATUS_REG);
356 ltssm_state = PCIE_LTSSM_STATE(val) >= ARRAY_SIZE(ltssm_str) ?
357 "Unknown state" : ltssm_str[PCIE_LTSSM_STATE(val)];
358 printk(BIOS_ERR, "%s: PCIe link down, current ltssm state: %s\n",
359 __func__, ltssm_state);
360 return;
363 printk(BIOS_INFO, "%s: PCIe link up success (%ld tries)\n", __func__,
364 tries);