1 /* SPDX-License-Identifier: GPL-2.0-only */
2
3 #include <boot/coreboot_tables.h>
4 #include <console/console.h>
5 #include <delay.h>
6 #include <device/device.h>
7 #include <device/mmio.h>
8 #include <device/pci.h>
9 #include <device/pci_ids.h>
10 #include <gpio.h>
11 #include <soc/clock.h>
12 #include <soc/qcom_qmp_phy.h>
13 #include <soc/pcie.h>
14 #include <timer.h>
15
16 #define ROOT_PORT_BDF 0x0
17 #define ATU_CTRL2 PCIE_ATU_UNR_REGION_CTRL2
18
19 static struct qcom_pcie_cntlr_t qcom_pcie_cfg;
20
dw_pcie_dbi_rd_wr(bool enable)21 static inline void dw_pcie_dbi_rd_wr(bool enable)
22 {
23 uint32_t val;
24 pcie_cntlr_cfg_t *pcierc = qcom_pcie_cfg.cntlr_cfg;
25
26 val = read32(pcierc->dbi_base + PCIE_DBI_MISC_CONTROL_1_OFF);
27
28 if (enable)
29 val |= PCIE_DBI_RO_WR_EN;
30 else
31 val &= ~PCIE_DBI_RO_WR_EN;
32
33 write32(pcierc->dbi_base + PCIE_DBI_MISC_CONTROL_1_OFF, val);
34 }
35
dw_pcie_writel_iatu(unsigned int index,uint32_t reg,uint32_t val)36 static void dw_pcie_writel_iatu(unsigned int index, uint32_t reg, uint32_t val)
37 {
38 pcie_cntlr_cfg_t *pcierc = qcom_pcie_cfg.cntlr_cfg;
39 unsigned int offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
40
41 write32(pcierc->atu_base + offset + reg, val);
42 }
43
dw_pcie_readl_iatu(unsigned int index,uint32_t reg)44 static uint32_t dw_pcie_readl_iatu(unsigned int index, uint32_t reg)
45 {
46 pcie_cntlr_cfg_t *pcierc = qcom_pcie_cfg.cntlr_cfg;
47 unsigned int offset = PCIE_GET_ATU_OUTB_UNR_REG_OFFSET(index);
48
49 return read32(pcierc->atu_base + offset + reg);
50 }
51
qcom_dw_pcie_prog_outbound_atu(unsigned int index,unsigned int type,uint64_t cpu_addr,uint64_t pcie_addr,uint32_t size)52 static void qcom_dw_pcie_prog_outbound_atu(unsigned int index,
53 unsigned int type, uint64_t cpu_addr,
54 uint64_t pcie_addr, uint32_t size)
55 {
56 dw_pcie_writel_iatu(index, PCIE_ATU_UNR_LOWER_BASE, lower_32_bits(cpu_addr));
57 dw_pcie_writel_iatu(index, PCIE_ATU_UNR_UPPER_BASE, upper_32_bits(cpu_addr));
58 dw_pcie_writel_iatu(index, PCIE_ATU_UNR_LIMIT, lower_32_bits(cpu_addr + size - 1));
59 dw_pcie_writel_iatu(index, PCIE_ATU_UNR_LOWER_TARGET, lower_32_bits(pcie_addr));
60 dw_pcie_writel_iatu(index, PCIE_ATU_UNR_UPPER_TARGET, upper_32_bits(pcie_addr));
61 dw_pcie_writel_iatu(index, PCIE_ATU_UNR_REGION_CTRL1, type);
62 dw_pcie_writel_iatu(index, PCIE_ATU_UNR_REGION_CTRL2, PCIE_ATU_ENABLE);
63
64 /* Ensure ATU enable takes effect before any subsequent config access */
65 if (retry(LINK_WAIT_MAX_IATU_RETRIES,
66 (dw_pcie_readl_iatu(index, ATU_CTRL2) & PCIE_ATU_ENABLE),
67 udelay(LINK_WAIT_IATU)))
68 return;
69
70 printk(BIOS_ERR, "PCIe o/b iATU couldn't be enabled after 5ms\n");
71 }
72
qcom_pcie_configure_gpios(pcie_cntlr_cfg_t * cfg)73 static void qcom_pcie_configure_gpios(pcie_cntlr_cfg_t *cfg)
74 {
75 gpio_configure(cfg->perst, 0, GPIO_NO_PULL, GPIO_16MA, GPIO_OUTPUT);
76 }
77
78 /**
79 * qcom_dw_pcie_configure() - Configure link capabilities and speed
80 *
81 * Configure the link capabilities and speed in the PCIe root complex.
82 */
qcom_dw_pcie_configure(uint32_t cap_speed)83 static void qcom_dw_pcie_configure(uint32_t cap_speed)
84 {
85 pcie_cntlr_cfg_t *pcierc = qcom_pcie_cfg.cntlr_cfg;
86
87 dw_pcie_dbi_rd_wr(true);
88
89 clrsetbits32(pcierc->dbi_base + PCIE_LINK_CAPABILITY,
90 TARGET_LINK_SPEED_MASK, cap_speed);
91
92 clrsetbits32(pcierc->dbi_base + PCIE_LINK_CTL_2,
93 TARGET_LINK_SPEED_MASK, cap_speed);
94
95 dw_pcie_dbi_rd_wr(false);
96 printk(BIOS_INFO, "PCIe Link speed configured in Gen %d\n", cap_speed);
97 }
98
99 /**
100 * is_pcie_link_up() - Return the link state
101 *
102 * Return: true for active link and false for no link
103 */
is_pcie_link_up(struct qcom_pcie_cntlr_t * pci)104 static bool is_pcie_link_up(struct qcom_pcie_cntlr_t *pci)
105 {
106 /* Read link status register */
107 return !!(read32(pci->cntlr_cfg->elbi + PCIE3X2_ELBI_SYS_STTS) & XMLH_LINK_UP);
108 }
109
110 /**
111 * wait_link_up() - Wait for the link to come up
112 *
113 * Return: true for active line and false for no link (timeout)
114 */
wait_link_up(struct qcom_pcie_cntlr_t * pci)115 static bool wait_link_up(struct qcom_pcie_cntlr_t *pci)
116 {
117 /* Check if the link is up or not */
118 if (retry(LINK_WAIT_MAX_RETRIES, is_pcie_link_up(pci), mdelay(PCIE_LINK_UP_MS)))
119 return true;
120
121 printk(BIOS_ERR, "PCIe link is not up even after 1sec\n");
122 return false;
123 }
124
qcom_pcie_dw_link_up(struct qcom_pcie_cntlr_t * pcie)125 static enum cb_err qcom_pcie_dw_link_up(struct qcom_pcie_cntlr_t *pcie)
126 {
127 if (is_pcie_link_up(pcie)) {
128 printk(BIOS_INFO, "PCIe Link is already up\n");
129 return CB_SUCCESS;
130 }
131
132 /* DW pre link configurations */
133 qcom_dw_pcie_configure(LINK_SPEED_GEN_2);
134
135 /* enable link training */
136 setbits32(pcie->cntlr_cfg->parf + PCIE_PARF_LTSSM, LTSSM_EN);
137
138 /* Check that link was established */
139 if (wait_link_up(pcie)) {
140 printk(BIOS_INFO, "PCIe link is up\n");
141 return CB_SUCCESS;
142 }
143
144 /*
145 * Link can be established in Gen 1 as it failed to establish in Gen2.
146 * So allow some time to do it.
147 */
148 udelay(100);
149
150 return CB_ERR;
151 }
152
153 /**
154 * Returns root port config space address or endpoint config space address.
155 * For endpoint config address, mapping would be done with ATU.
156 */
qcom_dw_pcie_get_config_addr(struct qcom_pcie_cntlr_t * pcierc,pci_devfn_t dev)157 static void *qcom_dw_pcie_get_config_addr(struct qcom_pcie_cntlr_t *pcierc,
158 pci_devfn_t dev)
159 {
160 unsigned int atu_type, cfg_size;
161 void *cfg_address;
162 uint32_t bus, busdev, devfn;
163 pcie_cntlr_cfg_t *cntlr = pcierc->cntlr_cfg;
164 bus = PCI_DEV2SEGBUS(dev);
165 devfn = PCI_DEV2DEVFN(dev);
166
167 busdev = PCIE_ATU_BUS(bus) |
168 PCIE_ATU_DEV(PCI_SLOT(devfn)) |
169 PCIE_ATU_FUNC(PCI_FUNC(devfn));
170
171 /* Accessing root port configuration space */
172 if (!bus && !devfn) {
173 cfg_address = pcierc->cntlr_cfg->dbi_base;
174 return cfg_address;
175 }
176
177 /* For local bus use CFG0 type */
178 atu_type = (bus == 1) ? PCIE_ATU_TYPE_CFG0 : PCIE_ATU_TYPE_CFG1;
179
180 cfg_address = cntlr->cfg_base + (cntlr->cfg_size * devfn);
181 cfg_size = cntlr->cfg_size;
182
183 qcom_dw_pcie_prog_outbound_atu(PCIE_ATU_REGION_INDEX1, atu_type,
184 (uint64_t)cfg_address, busdev, cfg_size);
185 return cfg_address;
186 }
187
qcom_dw_pcie_setup_rc(struct qcom_pcie_cntlr_t * pcie)188 static void qcom_dw_pcie_setup_rc(struct qcom_pcie_cntlr_t *pcie)
189 {
190 uint32_t val;
191 pcie_cntlr_cfg_t *pcierc = pcie->cntlr_cfg;
192 /*
193 * Enable DBI read-only registers for writing/updating configuration.
194 * Write permission gets disabled towards the end of this function.
195 */
196 dw_pcie_dbi_rd_wr(true);
197
198 val = read32(pcierc->dbi_base + PCIE_PORT_LINK_CONTROL);
199 /* Set the number of lanes */
200 val &= ~PORT_LINK_MODE_MASK;
201
202 switch (pcierc->lanes) {
203 case 1:
204 val |= PORT_LINK_MODE_1_LANES;
205 break;
206 case 2:
207 val |= PORT_LINK_MODE_2_LANES;
208 break;
209 case 4:
210 val |= PORT_LINK_MODE_4_LANES;
211 break;
212 case 8:
213 val |= PORT_LINK_MODE_8_LANES;
214 break;
215 default:
216 printk(BIOS_INFO, "PCIe num-lanes %u: invalid value\n",
217 pcierc->lanes);
218 return;
219 }
220
221 write32(pcierc->dbi_base + PCIE_PORT_LINK_CONTROL, val);
222
223 /* Set link width speed control register */
224 val = read32(pcierc->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL);
225 val &= ~PORT_LOGIC_LINK_WIDTH_MASK;
226
227 switch (pcierc->lanes) {
228 case 1:
229 val |= PORT_LOGIC_LINK_WIDTH_1_LANES;
230 break;
231 case 2:
232 val |= PORT_LOGIC_LINK_WIDTH_2_LANES;
233 break;
234 case 4:
235 val |= PORT_LOGIC_LINK_WIDTH_4_LANES;
236 break;
237 case 8:
238 val |= PORT_LOGIC_LINK_WIDTH_8_LANES;
239 break;
240 default:
241 printk(BIOS_INFO, "PCIe invalid lanes option\n");
242 return;
243 }
244
245 write32(pcierc->dbi_base + PCIE_LINK_WIDTH_SPEED_CONTROL, val);
246
247 /* Setup bus numbers */
248 clrsetbits32(pcierc->dbi_base + PCI_PRIMARY_BUS, TYPE1_HDR_BUS_NUM_MASK,
249 ROOT_PORT_BUS_NUM);
250
251 /* Disable SMMU */
252 write32(pcierc->parf + PCIE_PARF_BDF_TO_SID_CFG, BDF_TO_SID_BYPASS);
253
254 /* Configure ATU for outbound accesses */
255 qcom_dw_pcie_prog_outbound_atu(PCIE_ATU_REGION_INDEX0,
256 PCIE_ATU_TYPE_MEM,
257 pcierc->mem.phys_start,
258 ROOT_PORT_BDF, pcierc->mem.size);
259
260 /* Program correct class for RC */
261 write16(pcierc->dbi_base + PCI_CLASS_DEVICE, PCI_CLASS_BRIDGE_PCI);
262
263 /* Disable write permission right after the update */
264 dw_pcie_dbi_rd_wr(false);
265 }
266
qcom_qmp_phy_config_lane(void * base,const struct qcom_qmp_phy_init_tbl tbl[],unsigned int num,uint8_t ln_mask)267 static void qcom_qmp_phy_config_lane(void *base, const struct qcom_qmp_phy_init_tbl tbl[],
268 unsigned int num, uint8_t ln_mask)
269 {
270 unsigned int i;
271 const struct qcom_qmp_phy_init_tbl *t = tbl;
272
273 for (i = 0; i < num; i++, t++) {
274 if (!(t->lane_mask & ln_mask))
275 continue;
276 write32(base + t->offset, t->val);
277 }
278 }
279
qcom_qmp_phy_configure(void * base,const struct qcom_qmp_phy_init_tbl tbl[],unsigned int num)280 static void qcom_qmp_phy_configure(void *base, const struct qcom_qmp_phy_init_tbl tbl[],
281 unsigned int num)
282 {
283 qcom_qmp_phy_config_lane(base, tbl, num, 0xff);
284 }
285
qcom_qmp_phy_power_on(pcie_qmp_phy_cfg_t * qphy)286 static enum cb_err qcom_qmp_phy_power_on(pcie_qmp_phy_cfg_t *qphy)
287 {
288 uint64_t lock_us;
289
290 /* Release powerdown mode and allow endpoint refclk drive */
291 write32(qphy->pcs + QPHY_PCS_PWR_DWN_CNTRL, SW_PWRDN | REFCLK_DRV_DSBL);
292
293 /* Serdes configuration */
294 qcom_qmp_phy_configure(qphy->serdes, qphy->serdes_tbl, qphy->serdes_tbl_num);
295
296 /* Tx, Rx, and PCS configurations */
297 qcom_qmp_phy_config_lane(qphy->tx0, qphy->tx_tbl, qphy->tx_tbl_num, 1);
298 qcom_qmp_phy_config_lane(qphy->tx0, qphy->tx_tbl_sec, qphy->tx_tbl_num_sec, 1);
299 qcom_qmp_phy_config_lane(qphy->tx1, qphy->tx_tbl, qphy->tx_tbl_num, 2);
300 qcom_qmp_phy_config_lane(qphy->tx1, qphy->tx_tbl_sec, qphy->tx_tbl_num_sec, 2);
301 qcom_qmp_phy_config_lane(qphy->rx0, qphy->rx_tbl, qphy->rx_tbl_num, 1);
302 qcom_qmp_phy_config_lane(qphy->rx0, qphy->rx_tbl_sec, qphy->rx_tbl_num_sec, 1);
303 qcom_qmp_phy_config_lane(qphy->rx1, qphy->rx_tbl, qphy->rx_tbl_num, 2);
304 qcom_qmp_phy_config_lane(qphy->rx1, qphy->rx_tbl_sec, qphy->rx_tbl_num_sec, 2);
305 qcom_qmp_phy_configure(qphy->pcs, qphy->pcs_tbl, qphy->pcs_tbl_num);
306 qcom_qmp_phy_configure(qphy->pcs, qphy->pcs_tbl_sec, qphy->pcs_tbl_num_sec);
307 qcom_qmp_phy_configure(qphy->pcs_misc, qphy->pcs_misc_tbl, qphy->pcs_misc_tbl_num);
308 qcom_qmp_phy_configure(qphy->pcs_misc, qphy->pcs_misc_tbl_sec, qphy->pcs_tbl_num_sec);
309
310 /* Release software reset of PCS/Serdes */
311 clrbits32(qphy->pcs + QPHY_SW_RESET, SW_RESET);
312
313 /* start PCS/Serdes to operation mode */
314 write32(qphy->pcs + QPHY_START_CTRL, PCS_START | SERDES_START);
315
316 /*
317 * Wait for PHY initialization to be done
318 * PCS_STATUS: wait for 1ms for PHY STATUS bit to be set
319 */
320 lock_us = wait_us(1000, !(read32(qphy->qmp_phy_base + QPHY_PCS_STATUS) & PHY_STATUS));
321 if (!lock_us) {
322 printk(BIOS_ERR, "PCIe QMP PHY PLL failed to lock in 1ms\n");
323 return CB_ERR;
324 }
325
326 printk(BIOS_DEBUG, "PCIe QPHY Initialized took %lldus\n", lock_us);
327
328 qcom_dw_pcie_enable_pipe_clock();
329
330 return CB_SUCCESS;
331 }
332
333 /*
334 * Reset the PCIe PHY core.
335 * Allow 100us delay to ensure reset is asserted.
336 */
qcom_qmp_reset_phy(struct qcom_pcie_cntlr_t * pcie)337 static void qcom_qmp_reset_phy(struct qcom_pcie_cntlr_t *pcie)
338 {
339 clock_reset_bcr(pcie->cntlr_cfg->qmp_phy_bcr, 1);
340 udelay(100);
341 clock_reset_bcr(pcie->cntlr_cfg->qmp_phy_bcr, 0);
342 }
343
344 /*
345 * Reset the PCIe controller core.
346 * Allow 100us delay to ensure reset is asserted.
347 */
qcom_dw_pcie_reset_core(struct qcom_pcie_cntlr_t * pcie)348 static void qcom_dw_pcie_reset_core(struct qcom_pcie_cntlr_t *pcie)
349 {
350 clock_reset_bcr(pcie->cntlr_cfg->pcie_bcr, 1);
351 udelay(100);
352 clock_reset_bcr(pcie->cntlr_cfg->pcie_bcr, 0);
353 }
354
qcom_dw_pcie_enable(struct qcom_pcie_cntlr_t * pcie)355 static enum cb_err qcom_dw_pcie_enable(struct qcom_pcie_cntlr_t *pcie)
356 {
357 int ret;
358
359 pcie_cntlr_cfg_t *pcierc = pcie->cntlr_cfg;
360 pcie_qmp_phy_cfg_t *qmp_phy = pcie->qmp_phy_cfg;
361
362 /* assert PCIe reset link to keep EP in reset */
363 gpio_set(pcierc->perst, 0);
364
365 /* Enable PCIe controller and SoC specific clocks */
366 ret = qcom_dw_pcie_enable_clock();
367 if (ret) {
368 printk(BIOS_ERR, "Enable PCIe clocks failed\n");
369 return ret;
370 }
371
372 /* Reset the controller */
373 qcom_dw_pcie_reset_core(pcie);
374
375 /* configure PCIe to RC mode */
376 write32(pcierc->parf + PCIE_PARF_DEVICE_TYPE, DEVICE_TYPE_RC);
377
378 /* Power on the PHY */
379 clrbits32(pcierc->parf + PCIE_PARF_PHY_CTRL, PHY_PWR_DOWN);
380
381 /* MAC PHY_POWERDOWN MUX DISABLE */
382 clrbits32(pcierc->parf + PCIE_PARF_SYS_CTRL, MAC_PHY_PWRDOWN_MUX_EN);
383
384 /* Bypass MHI as its not needed */
385 setbits32(pcierc->parf + PCIE_PARF_MHI_CLOCK_RESET_CTRL, MHI_BYPASS);
386
387 qcom_qmp_reset_phy(pcie);
388
389 /* Initialize QMP PHY */
390 ret = qcom_qmp_phy_power_on(qmp_phy);
391 if (ret) {
392 printk(BIOS_ERR, "PCIe PHY init failed\n");
393 return ret;
394 }
395
396 qcom_dw_pcie_setup_rc(pcie);
397
398 /* de-assert PCIe reset link to bring EP out of reset */
399 gpio_set(pcierc->perst, 1);
400
401 /* establisth the link */
402 ret = qcom_pcie_dw_link_up(pcie);
403 if (ret) {
404 printk(BIOS_ERR, "PCIe Link init failed\n");
405 return ret;
406 }
407
408 return CB_SUCCESS;
409 }
410
411 /**
412 * Fill coreboot table with PCIe info.
413 * It allows exporting this info to payloads.
414 */
fill_lb_pcie(struct lb_pcie * pcie)415 enum cb_err fill_lb_pcie(struct lb_pcie *pcie)
416 {
417 if (!mainboard_needs_pcie_init())
418 return CB_ERR_NOT_IMPLEMENTED;
419
420 pcie_cntlr_cfg_t *pcierc = qcom_pcie_cfg.cntlr_cfg;
421 pcie->ctrl_base = (uintptr_t)pcierc->dbi_base;
422 return CB_SUCCESS;
423 }
424
425 /* map_bus function for mapping pcie_s_{read/write}_configXX() functions */
pci_map_bus(pci_devfn_t dev)426 volatile union pci_bank *pci_map_bus(pci_devfn_t dev)
427 {
428 void *config_addr = NULL;
429
430 config_addr = qcom_dw_pcie_get_config_addr(&qcom_pcie_cfg, dev);
431 return (void *)config_addr;
432 }
433
434 /* PCI domain ops read_resources callback */
qcom_pci_domain_read_resources(struct device * dev)435 void qcom_pci_domain_read_resources(struct device *dev)
436 {
437 struct resource *res;
438 pcie_cntlr_cfg_t *pcierc = qcom_pcie_cfg.cntlr_cfg;
439
440 /* Initialize the system-wide I/O space constraints. */
441 res = new_resource(dev, IOINDEX_SUBTRACTIVE(0, 0));
442 res->base = pcierc->io.phys_start;
443 res->limit = pcierc->io.size - 1;
444 res->flags = IORESOURCE_IO | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
445
446 /* Initialize the system-wide memory resources constraints. */
447 res = new_resource(dev, IOINDEX_SUBTRACTIVE(1, 0));
448 res->base = pcierc->mem.phys_start;
449 res->limit = pcierc->mem.size - 1;
450 res->flags = IORESOURCE_MEM | IORESOURCE_SUBTRACTIVE | IORESOURCE_ASSIGNED;
451 }
452
453 /* PCI domain ops enable callback */
qcom_setup_pcie_host(struct device * dev)454 void qcom_setup_pcie_host(struct device *dev)
455 {
456 gcom_pcie_get_config(&qcom_pcie_cfg);
457
458 /* Ensure PCIe endpoints are powered-on before initiating PCIe link training */
459 gcom_pcie_power_on_ep();
460
461 printk(BIOS_INFO, "Setup PCIe in RC mode\n");
462
463 /* Configure PERST gpio */
464 qcom_pcie_configure_gpios(qcom_pcie_cfg.cntlr_cfg);
465
466 if (!qcom_dw_pcie_enable(&qcom_pcie_cfg))
467 printk(BIOS_NOTICE, "PCIe enumerated succussfully..\n");
468 else
469 printk(BIOS_EMERG, "Failed to enable PCIe\n");
470 }
471