Skip to content

Commit 1276ad0

Browse files
committed
Merge branch 'pci/controller/mediatek'
- Use clk_bulk_prepare_enable() instead of separate clk_bulk_prepare() and clk_bulk_enable() (Lorenzo Bianconi) - Rearrange reset assert/deassert so they're both done in the *_power_up() callbacks (Lorenzo Bianconi) - Document that Airoha EN7581 requires PHY init and power-on before PHY reset deassert, unlike other MediaTek Gen3 controllers (Lorenzo Bianconi) - Move Airoha EN7581 post-reset delay from the en7581 clock .enable() method to mtk_pcie_en7581_power_up() (Lorenzo Bianconi) - Sleep instead of delay during Airoha EN7581 power-up, since this is a non-atomic context (Lorenzo Bianconi) - Skip PERST# assertion on Airoha EN7581 during probe and suspend/resume to avoid a hardware defect (Lorenzo Bianconi) - Enable async probe to reduce system startup time (Douglas Anderson) * pci/controller/mediatek: PCI: mediatek-gen3: Enable async probe by default PCI: mediatek-gen3: Avoid PCIe resetting via PERST# for Airoha EN7581 SoC PCI: mediatek-gen3: Rely on msleep() in mtk_pcie_en7581_power_up() PCI: mediatek-gen3: Move reset delay in mtk_pcie_en7581_power_up() PCI: mediatek-gen3: Add comment about initialization order in mtk_pcie_en7581_power_up() PCI: mediatek-gen3: Move reset/assert callbacks in .power_up() PCI: mediatek-gen3: Rely on clk_bulk_prepare_enable() in mtk_pcie_en7581_power_up()
2 parents 09b7c16 + 17bd5e4 commit 1276ad0

File tree

2 files changed

+76
-42
lines changed

2 files changed

+76
-42
lines changed

drivers/clk/clk-en7523.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -477,7 +477,6 @@ static int en7581_pci_enable(struct clk_hw *hw)
477477
REG_PCI_CONTROL_PERSTOUT;
478478
val = readl(np_base + REG_PCI_CONTROL);
479479
writel(val | mask, np_base + REG_PCI_CONTROL);
480-
msleep(250);
481480

482481
return 0;
483482
}

drivers/pci/controller/pcie-mediatek-gen3.c

Lines changed: 76 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -125,6 +125,8 @@
125125

126126
#define MAX_NUM_PHY_RESETS 3
127127

128+
#define PCIE_MTK_RESET_TIME_US 10
129+
128130
/* Time in ms needed to complete PCIe reset on EN7581 SoC */
129131
#define PCIE_EN7581_RESET_TIME_MS 100
130132

@@ -133,17 +135,26 @@ struct mtk_gen3_pcie;
133135
#define PCIE_CONF_LINK2_CTL_STS (PCIE_CFG_OFFSET_ADDR + 0xb0)
134136
#define PCIE_CONF_LINK2_LCR2_LINK_SPEED GENMASK(3, 0)
135137

138+
enum mtk_gen3_pcie_flags {
139+
SKIP_PCIE_RSTB = BIT(0), /* Skip PERST# assertion during device
140+
* probing or suspend/resume phase to
141+
* avoid hw bugs/issues.
142+
*/
143+
};
144+
136145
/**
137146
* struct mtk_gen3_pcie_pdata - differentiate between host generations
138147
* @power_up: pcie power_up callback
139148
* @phy_resets: phy reset lines SoC data.
149+
* @flags: pcie device flags.
140150
*/
141151
struct mtk_gen3_pcie_pdata {
142152
int (*power_up)(struct mtk_gen3_pcie *pcie);
143153
struct {
144154
const char *id[MAX_NUM_PHY_RESETS];
145155
int num_resets;
146156
} phy_resets;
157+
u32 flags;
147158
};
148159

149160
/**
@@ -438,22 +449,33 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
438449
val |= PCIE_DISABLE_DVFSRC_VLT_REQ;
439450
writel_relaxed(val, pcie->base + PCIE_MISC_CTRL_REG);
440451

441-
/* Assert all reset signals */
442-
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
443-
val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB;
444-
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
445-
446452
/*
447-
* Described in PCIe CEM specification sections 2.2 (PERST# Signal)
448-
* and 2.2.1 (Initial Power-Up (G3 to S0)).
449-
* The deassertion of PERST# should be delayed 100ms (TPVPERL)
450-
* for the power and clock to become stable.
453+
* Airoha EN7581 has a hw bug asserting/releasing PCIE_PE_RSTB signal
454+
* causing occasional PCIe link down. In order to overcome the issue,
455+
* PCIE_RSTB signals are not asserted/released at this stage and the
456+
* PCIe block is reset using en7523_reset_assert() and
457+
* en7581_pci_enable().
451458
*/
452-
msleep(100);
453-
454-
/* De-assert reset signals */
455-
val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB);
456-
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
459+
if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
460+
/* Assert all reset signals */
461+
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
462+
val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
463+
PCIE_PE_RSTB;
464+
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
465+
466+
/*
467+
* Described in PCIe CEM specification revision 6.0.
468+
*
469+
* The deassertion of PERST# should be delayed 100ms (TPVPERL)
470+
* for the power and clock to become stable.
471+
*/
472+
msleep(PCIE_T_PVPERL_MS);
473+
474+
/* De-assert reset signals */
475+
val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
476+
PCIE_PE_RSTB);
477+
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
478+
}
457479

458480
/* Check if the link is up or not */
459481
err = readl_poll_timeout(pcie->base + PCIE_LINK_STATUS_REG, val,
@@ -913,11 +935,20 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
913935
u32 val;
914936

915937
/*
916-
* Wait for the time needed to complete the bulk assert in
917-
* mtk_pcie_setup for EN7581 SoC.
938+
* The controller may have been left out of reset by the bootloader
939+
* so make sure that we get a clean start by asserting resets here.
918940
*/
919-
mdelay(PCIE_EN7581_RESET_TIME_MS);
941+
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets,
942+
pcie->phy_resets);
943+
reset_control_assert(pcie->mac_reset);
920944

945+
/* Wait for the time needed to complete the reset lines assert. */
946+
msleep(PCIE_EN7581_RESET_TIME_MS);
947+
948+
/*
949+
* Unlike the other MediaTek Gen3 controllers, the Airoha EN7581
950+
* requires PHY initialization and power-on before PHY reset deassert.
951+
*/
921952
err = phy_init(pcie->phy);
922953
if (err) {
923954
dev_err(dev, "failed to initialize PHY\n");
@@ -940,17 +971,11 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
940971
* Wait for the time needed to complete the bulk de-assert above.
941972
* This time is specific for EN7581 SoC.
942973
*/
943-
mdelay(PCIE_EN7581_RESET_TIME_MS);
974+
msleep(PCIE_EN7581_RESET_TIME_MS);
944975

945976
pm_runtime_enable(dev);
946977
pm_runtime_get_sync(dev);
947978

948-
err = clk_bulk_prepare(pcie->num_clks, pcie->clks);
949-
if (err) {
950-
dev_err(dev, "failed to prepare clock\n");
951-
goto err_clk_prepare;
952-
}
953-
954979
val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
955980
FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
956981
FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
@@ -963,17 +988,22 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
963988
FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
964989
writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG);
965990

966-
err = clk_bulk_enable(pcie->num_clks, pcie->clks);
991+
err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
967992
if (err) {
968993
dev_err(dev, "failed to prepare clock\n");
969-
goto err_clk_enable;
994+
goto err_clk_prepare_enable;
970995
}
971996

997+
/*
998+
* Airoha EN7581 performs PCIe reset via clk callbacks since it has a
999+
* hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to
1000+
* complete the PCIe reset.
1001+
*/
1002+
msleep(PCIE_T_PVPERL_MS);
1003+
9721004
return 0;
9731005

974-
err_clk_enable:
975-
clk_bulk_unprepare(pcie->num_clks, pcie->clks);
976-
err_clk_prepare:
1006+
err_clk_prepare_enable:
9771007
pm_runtime_put_sync(dev);
9781008
pm_runtime_disable(dev);
9791009
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
@@ -990,6 +1020,15 @@ static int mtk_pcie_power_up(struct mtk_gen3_pcie *pcie)
9901020
struct device *dev = pcie->dev;
9911021
int err;
9921022

1023+
/*
1024+
* The controller may have been left out of reset by the bootloader
1025+
* so make sure that we get a clean start by asserting resets here.
1026+
*/
1027+
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets,
1028+
pcie->phy_resets);
1029+
reset_control_assert(pcie->mac_reset);
1030+
usleep_range(PCIE_MTK_RESET_TIME_US, 2 * PCIE_MTK_RESET_TIME_US);
1031+
9931032
/* PHY power on and enable pipe clock */
9941033
err = reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
9951034
if (err) {
@@ -1074,14 +1113,6 @@ static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie)
10741113
* counter since the bulk is shared.
10751114
*/
10761115
reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
1077-
/*
1078-
* The controller may have been left out of reset by the bootloader
1079-
* so make sure that we get a clean start by asserting resets here.
1080-
*/
1081-
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
1082-
1083-
reset_control_assert(pcie->mac_reset);
1084-
usleep_range(10, 20);
10851116

10861117
/* Don't touch the hardware registers before power up */
10871118
err = pcie->soc->power_up(pcie);
@@ -1231,10 +1262,12 @@ static int mtk_pcie_suspend_noirq(struct device *dev)
12311262
return err;
12321263
}
12331264

1234-
/* Pull down the PERST# pin */
1235-
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
1236-
val |= PCIE_PE_RSTB;
1237-
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
1265+
if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
1266+
/* Assert the PERST# pin */
1267+
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
1268+
val |= PCIE_PE_RSTB;
1269+
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
1270+
}
12381271

12391272
dev_dbg(pcie->dev, "entered L2 states successfully");
12401273

@@ -1285,6 +1318,7 @@ static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_en7581 = {
12851318
.id[2] = "phy-lane2",
12861319
.num_resets = 3,
12871320
},
1321+
.flags = SKIP_PCIE_RSTB,
12881322
};
12891323

12901324
static const struct of_device_id mtk_pcie_of_match[] = {
@@ -1301,6 +1335,7 @@ static struct platform_driver mtk_pcie_driver = {
13011335
.name = "mtk-pcie-gen3",
13021336
.of_match_table = mtk_pcie_of_match,
13031337
.pm = &mtk_pcie_pm_ops,
1338+
.probe_type = PROBE_PREFER_ASYNCHRONOUS,
13041339
},
13051340
};
13061341

0 commit comments

Comments
 (0)