|
134 | 134 | PCIE_MISC_CPU_2_PCIE_MEM_WIN0_LIMIT_HI + ((win) * 8)
|
135 | 135 |
|
136 | 136 | #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_CLKREQ_DEBUG_ENABLE_MASK 0x2
|
| 137 | +#define PCIE_MISC_HARD_PCIE_HARD_DEBUG_PERST_ASSERT_MASK 0x8 |
137 | 138 | #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_L1SS_ENABLE_MASK 0x200000
|
138 | 139 | #define PCIE_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x08000000
|
139 | 140 | #define PCIE_BMIPS_MISC_HARD_PCIE_HARD_DEBUG_SERDES_IDDQ_MASK 0x00800000
|
@@ -360,6 +361,7 @@ struct brcm_pcie {
|
360 | 361 | struct subdev_regulators *sr;
|
361 | 362 | bool ep_wakeup_capable;
|
362 | 363 | const struct pcie_cfg_data *cfg;
|
| 364 | + u32 tperst_clk_ms; |
363 | 365 | };
|
364 | 366 |
|
365 | 367 | static inline bool is_bmips(const struct brcm_pcie *pcie)
|
@@ -1487,13 +1489,32 @@ static int brcm_pcie_start_link(struct brcm_pcie *pcie)
|
1487 | 1489 | u16 nlw, cls, lnksta, tmp16;
|
1488 | 1490 | bool ssc_good = false;
|
1489 | 1491 | int ret, i;
|
| 1492 | + u32 tmp; |
1490 | 1493 |
|
1491 | 1494 | /* Limit the generation if specified */
|
1492 | 1495 | if (pcie->gen)
|
1493 | 1496 | brcm_pcie_set_gen(pcie, pcie->gen);
|
1494 | 1497 |
|
1495 | 1498 | /* Unassert the fundamental reset */
|
1496 |
| - ret = pcie->cfg->perst_set(pcie, 0); |
| 1499 | + if (pcie->tperst_clk_ms) { |
| 1500 | + /* |
| 1501 | + * Increase Tperst_clk time by forcing PERST# output low while |
| 1502 | + * the internal reset is released, so the PLL generates stable |
| 1503 | + * refclk output further in advance of PERST# deassertion. |
| 1504 | + */ |
| 1505 | + tmp = readl(pcie->base + HARD_DEBUG(pcie)); |
| 1506 | + u32p_replace_bits(&tmp, 1, PCIE_MISC_HARD_PCIE_HARD_DEBUG_PERST_ASSERT_MASK); |
| 1507 | + writel(tmp, pcie->base + HARD_DEBUG(pcie)); |
| 1508 | + |
| 1509 | + ret = pcie->cfg->perst_set(pcie, 0); |
| 1510 | + fsleep(pcie->tperst_clk_ms * USEC_PER_MSEC); |
| 1511 | + |
| 1512 | + tmp = readl(pcie->base + HARD_DEBUG(pcie)); |
| 1513 | + u32p_replace_bits(&tmp, 0, PCIE_MISC_HARD_PCIE_HARD_DEBUG_PERST_ASSERT_MASK); |
| 1514 | + writel(tmp, pcie->base + HARD_DEBUG(pcie)); |
| 1515 | + } else { |
| 1516 | + ret = pcie->cfg->perst_set(pcie, 0); |
| 1517 | + } |
1497 | 1518 | if (ret)
|
1498 | 1519 | return ret;
|
1499 | 1520 |
|
@@ -2058,6 +2079,8 @@ static int brcm_pcie_probe(struct platform_device *pdev)
|
2058 | 2079 | pcie->ssc = !(pcie->cfg->quirks & CFG_QUIRK_NO_SSC) &&
|
2059 | 2080 | of_property_read_bool(np, "brcm,enable-ssc");
|
2060 | 2081 |
|
| 2082 | + of_property_read_u32(np, "brcm,tperst-clk-ms", &pcie->tperst_clk_ms); |
| 2083 | + |
2061 | 2084 | pcie->rescal = devm_reset_control_get_optional_shared(&pdev->dev, "rescal");
|
2062 | 2085 | if (IS_ERR(pcie->rescal))
|
2063 | 2086 | return PTR_ERR(pcie->rescal);
|
|
0 commit comments