xref: /aosp_15_r20/external/coreboot/src/soc/mediatek/common/pcie.c (revision b9411a12aaaa7e1e6a6fb7c5e057f44ee179a49c)
1 /* SPDX-License-Identifier: GPL-2.0-only */
2 
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>
17 
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)
22 
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))
29 
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)
35 
36 #define PCIE_LTSSM_STATUS_REG		0x150
37 #define PCIE_LTSSM_STATE(val)		(((val) >> 24) & 0x1f)
38 
39 #define PCIE_LINK_STATUS_REG		0x154
40 #define PCIE_CTRL_LINKUP		BIT(8)
41 
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)
47 
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
54 
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)
65 
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 */
95 };
96 
mtk_pcie_get_controller_base(pci_devfn_t devfn)97 static uintptr_t mtk_pcie_get_controller_base(pci_devfn_t devfn)
98 {
99 	struct device *root_dev;
100 	const mtk_soc_config_t *config;
101 	static uintptr_t base = 0;
102 
103 	if (!base) {
104 		root_dev = pcidev_path_on_root(devfn);
105 		config = config_of(root_dev);
106 		base = config->pcie_config.base;
107 	}
108 
109 	return base;
110 }
111 
pci_map_bus(pci_devfn_t dev)112 volatile union pci_bank *pci_map_bus(pci_devfn_t dev)
113 {
114 	u32 val, devfn, bus;
115 	uintptr_t base;
116 
117 	devfn = PCI_DEV2DEVFN(dev);
118 	bus = PCI_DEV2SEGBUS(dev);
119 	val = PCIE_CFG_HEADER(bus, devfn);
120 
121 	base = mtk_pcie_get_controller_base(dev);
122 	write32p(base + PCIE_CFGNUM_REG, val);
123 
124 	return (void *)(base + PCIE_CFG_OFFSET_ADDR);
125 }
126 
mtk_pcie_set_table(uintptr_t table,uint32_t cpu_addr,uint32_t pci_addr,uint32_t size,uint32_t attr)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)
129 {
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);
135 }
136 
mtk_pcie_set_trans_window(size_t * count,uintptr_t table_base,const struct mtk_pcie_mmio_res * mmio_res)137 static int mtk_pcie_set_trans_window(size_t *count, uintptr_t table_base,
138 				     const struct mtk_pcie_mmio_res *mmio_res)
139 {
140 	const char *range_type;
141 	uintptr_t table;
142 	uint32_t table_attr;
143 	uint32_t cpu_addr, pci_addr, remaining, size;
144 
145 	if (!mmio_res)
146 		return -1;
147 
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;
158 	}
159 
160 	cpu_addr = mmio_res->cpu_addr;
161 	pci_addr = mmio_res->pci_addr;
162 	remaining = mmio_res->size;
163 
164 	while (remaining && *count < PCIE_MAX_TRANS_TABLES) {
165 		/*
166 		 * The table size needs to be a power of 2.
167 		 * In addition, cpu_addr needs to be aligned to the size.
168 		 */
169 		size = BIT(__fls(remaining));
170 
171 		if (cpu_addr > 0)
172 			size = MIN(size, BIT(__ffs(cpu_addr)));
173 
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;
179 		}
180 
181 		table = table_base + *count * PCIE_ATR_TLB_SET_OFFSET;
182 		mtk_pcie_set_table(table, cpu_addr, pci_addr, size, table_attr);
183 
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)++;
191 	}
192 
193 	if (remaining) {
194 		printk(BIOS_ERR, "%s: Not enough translation windows, remaining size: %#x\n",
195 		       __func__, remaining);
196 		return -1;
197 	}
198 
199 	return 0;
200 }
201 
mtk_pcie_domain_new_res(struct device * dev,unsigned int index,const struct mtk_pcie_mmio_res * mmio_res)202 static void mtk_pcie_domain_new_res(struct device *dev, unsigned int index,
203 				    const struct mtk_pcie_mmio_res *mmio_res)
204 {
205 	struct resource *res;
206 
207 	if (!mmio_res)
208 		return;
209 
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;
215 }
216 
mtk_pcie_domain_read_resources(struct device * dev)217 void mtk_pcie_domain_read_resources(struct device *dev)
218 {
219 	const mtk_soc_config_t *config = config_of(dev);
220 	const struct mtk_pcie_config *conf = &config->pcie_config;
221 
222 	mtk_pcie_domain_new_res(dev, IOINDEX_SUBTRACTIVE(0, 0),
223 				&conf->mmio_res_io);
224 
225 	mtk_pcie_domain_new_res(dev, IOINDEX_SUBTRACTIVE(1, 0),
226 				&conf->mmio_res_mem);
227 }
228 
mtk_pcie_domain_set_resources(struct device * dev)229 void mtk_pcie_domain_set_resources(struct device *dev)
230 {
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;
235 
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;
241 	}
242 
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__);
246 
247 	pci_domain_set_resources(dev);
248 }
249 
fill_lb_pcie(struct lb_pcie * pcie)250 enum cb_err fill_lb_pcie(struct lb_pcie *pcie)
251 {
252 	if (!pci_root_bus())
253 		return CB_ERR;
254 
255 	pcie->ctrl_base = mtk_pcie_get_controller_base(0);
256 	return CB_SUCCESS;
257 }
258 
mtk_pcie_domain_enable(struct device * dev)259 void mtk_pcie_domain_enable(struct device *dev)
260 {
261 	const mtk_soc_config_t *config = config_of(dev);
262 	const struct mtk_pcie_config *conf = &config->pcie_config;
263 	const char *ltssm_state;
264 	long perst_time_us;
265 	size_t tries = 0;
266 	uint32_t val;
267 
268 	/* Set as RC mode */
269 	val = read32p(conf->base + PCIE_SETTING_REG);
270 	val |= PCIE_RC_MODE;
271 	write32p(conf->base + PCIE_SETTING_REG, val);
272 
273 	/* Set class code */
274 	val = read32p(conf->base + PCIE_PCI_IDS_1);
275 	val &= ~GENMASK(31, 8);
276 	val |= PCI_CLASS(PCI_CLASS_BRIDGE_PCI << 8);
277 	write32p(conf->base + PCIE_PCI_IDS_1, val);
278 
279 	/* Mask all INTx interrupts */
280 	val = read32p(conf->base + PCIE_INT_ENABLE_REG);
281 	val &= ~PCIE_INTX_ENABLE;
282 	write32p(conf->base + PCIE_INT_ENABLE_REG, val);
283 
284 	perst_time_us = early_init_get_elapsed_time_us(EARLY_INIT_PCIE);
285 	printk(BIOS_DEBUG, "%s: %ld us elapsed since assert PERST#\n",
286 	       __func__, perst_time_us);
287 
288 	/*
289 	 * Described in PCIe CEM specification sections 2.2
290 	 * (PERST# Signal) and 2.2.1 (Initial Power-Up (G3 to S0)).
291 	 * The deassertion of PERST# should be delayed 100ms (TPVPERL)
292 	 * for the power and clock to become stable.
293 	 */
294 	const long min_perst_time_us = 100000; /* 100 ms */
295 	if (perst_time_us < min_perst_time_us) {
296 		if (!perst_time_us) {
297 			printk(BIOS_WARNING,
298 			       "%s: PCIe early init data not found, sleeping 100ms\n",
299 			       __func__);
300 			mtk_pcie_reset(conf->base + PCIE_RST_CTRL_REG, true);
301 		} else {
302 			printk(BIOS_WARNING,
303 			       "%s: Need an extra %ld us delay to meet PERST# deassertion requirement\n",
304 			       __func__, min_perst_time_us - perst_time_us);
305 		}
306 
307 		udelay(min_perst_time_us - perst_time_us);
308 	}
309 
310 	/* De-assert reset signals */
311 	mtk_pcie_reset(conf->base + PCIE_RST_CTRL_REG, false);
312 
313 	if (!retry(100,
314 		   (tries++, read32p(conf->base + PCIE_LINK_STATUS_REG) &
315 		    PCIE_CTRL_LINKUP), mdelay(1))) {
316 		val = read32p(conf->base + PCIE_LTSSM_STATUS_REG);
317 		ltssm_state = PCIE_LTSSM_STATE(val) >= ARRAY_SIZE(ltssm_str) ?
318 			    "Unknown state" : ltssm_str[PCIE_LTSSM_STATE(val)];
319 		printk(BIOS_ERR, "%s: PCIe link down, current ltssm state: %s\n",
320 		       __func__, ltssm_state);
321 		return;
322 	}
323 
324 	printk(BIOS_INFO, "%s: PCIe link up success (%ld tries)\n", __func__,
325 	       tries);
326 }
327