mirror of
https://git.kernel.org/pub/scm/linux/kernel/git/next/linux-next.git
synced 2024-12-29 17:22:07 +00:00
Merge branch 'controller/mediatek'
* controller/mediatek: PCI: mediatek-gen3: Avoid PCIe resetting via PCIE_RSTB for Airoha EN7581 SoC PCI: mediatek-gen3: Use msleep() in mtk_pcie_en7581_power_up() PCI: mediatek-gen3: Add 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: Use clk_bulk_prepare_enable() in mtk_pcie_en7581_power_up() PCI: mediatek-gen3: Add missing reset_control_deassert() for mac_rst in mtk_pcie_en7581_power_up()
This commit is contained in:
commit
83a7a06fd9
@ -477,7 +477,6 @@ static int en7581_pci_enable(struct clk_hw *hw)
|
||||
REG_PCI_CONTROL_PERSTOUT;
|
||||
val = readl(np_base + REG_PCI_CONTROL);
|
||||
writel(val | mask, np_base + REG_PCI_CONTROL);
|
||||
msleep(250);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -125,18 +125,30 @@
|
||||
|
||||
#define MAX_NUM_PHY_RESETS 3
|
||||
|
||||
#define PCIE_MTK_RESET_TIME_US 10
|
||||
|
||||
/* Time in ms needed to complete PCIe reset on EN7581 SoC */
|
||||
#define PCIE_EN7581_RESET_TIME_MS 100
|
||||
|
||||
struct mtk_gen3_pcie;
|
||||
|
||||
#define PCIE_CONF_LINK2_CTL_STS (PCIE_CFG_OFFSET_ADDR + 0xb0)
|
||||
#define PCIE_CONF_LINK2_LCR2_LINK_SPEED GENMASK(3, 0)
|
||||
|
||||
struct mtk_gen3_pcie;
|
||||
|
||||
enum mtk_gen3_pcie_flags {
|
||||
SKIP_PCIE_RSTB = BIT(0), /*
|
||||
* Skip PCIE_RSTB signals configuration
|
||||
* during device probing or suspend/resume
|
||||
* phase in order to avoid hardware
|
||||
* bugs/issues.
|
||||
*/
|
||||
};
|
||||
|
||||
/**
|
||||
* struct mtk_gen3_pcie_pdata - differentiate between host generations
|
||||
* @power_up: pcie power_up callback
|
||||
* @phy_resets: phy reset lines SoC data.
|
||||
* @flags: pcie device flags.
|
||||
*/
|
||||
struct mtk_gen3_pcie_pdata {
|
||||
int (*power_up)(struct mtk_gen3_pcie *pcie);
|
||||
@ -144,6 +156,7 @@ struct mtk_gen3_pcie_pdata {
|
||||
const char *id[MAX_NUM_PHY_RESETS];
|
||||
int num_resets;
|
||||
} phy_resets;
|
||||
u32 flags;
|
||||
};
|
||||
|
||||
/**
|
||||
@ -438,22 +451,34 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
|
||||
val |= PCIE_DISABLE_DVFSRC_VLT_REQ;
|
||||
writel_relaxed(val, pcie->base + PCIE_MISC_CTRL_REG);
|
||||
|
||||
/* Assert all reset signals */
|
||||
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
|
||||
val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB;
|
||||
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
|
||||
/*
|
||||
* Described in PCIe CEM specification sections 2.2 (PERST# Signal)
|
||||
* and 2.2.1 (Initial Power-Up (G3 to S0)).
|
||||
* The deassertion of PERST# should be delayed 100ms (TPVPERL)
|
||||
* for the power and clock to become stable.
|
||||
* Airoha EN7581 has a hardware bug asserting/releasing PCIE_PE_RSTB
|
||||
* signal causing occasional PCIe link down. In order to overcome the
|
||||
* issue, PCIE_RSTB signals are not asserted/released at this stage
|
||||
* and the PCIe block is reset configuting REG_PCI_CONTROL (0x88) and
|
||||
* REG_RESET_CONTROL (0x834) registers available in the clock module
|
||||
* running clk_bulk_prepare_enable in mtk_pcie_en7581_power_up().
|
||||
*/
|
||||
msleep(100);
|
||||
if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
|
||||
/* Assert all reset signals */
|
||||
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
|
||||
val |= PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
|
||||
PCIE_PE_RSTB;
|
||||
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
|
||||
/* De-assert reset signals */
|
||||
val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB | PCIE_PE_RSTB);
|
||||
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
/*
|
||||
* Described in PCIe CEM specification sections 2.2 (PERST# Signal)
|
||||
* and 2.2.1 (Initial Power-Up (G3 to S0)).
|
||||
* The deassertion of PERST# should be delayed 100ms (TPVPERL)
|
||||
* for the power and clock to become stable.
|
||||
*/
|
||||
msleep(PCIE_T_PVPERL_MS);
|
||||
|
||||
/* De-assert reset signals */
|
||||
val &= ~(PCIE_MAC_RSTB | PCIE_PHY_RSTB | PCIE_BRG_RSTB |
|
||||
PCIE_PE_RSTB);
|
||||
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
}
|
||||
|
||||
/* Check if the link is up or not */
|
||||
err = readl_poll_timeout(pcie->base + PCIE_LINK_STATUS_REG, val,
|
||||
@ -913,11 +938,20 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
|
||||
u32 val;
|
||||
|
||||
/*
|
||||
* Wait for the time needed to complete the bulk assert in
|
||||
* mtk_pcie_setup for EN7581 SoC.
|
||||
* The controller may have been left out of reset by the bootloader
|
||||
* so make sure that we get a clean start by asserting resets here.
|
||||
*/
|
||||
mdelay(PCIE_EN7581_RESET_TIME_MS);
|
||||
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets,
|
||||
pcie->phy_resets);
|
||||
reset_control_assert(pcie->mac_reset);
|
||||
|
||||
/* Wait for the time needed to complete the reset lines assert. */
|
||||
msleep(PCIE_EN7581_RESET_TIME_MS);
|
||||
|
||||
/*
|
||||
* Unlike the other MediaTek Gen3 controllers, the Airoha EN7581
|
||||
* requires PHY initialization and power-on before PHY reset deassert.
|
||||
*/
|
||||
err = phy_init(pcie->phy);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to initialize PHY\n");
|
||||
@ -940,17 +974,14 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
|
||||
* Wait for the time needed to complete the bulk de-assert above.
|
||||
* This time is specific for EN7581 SoC.
|
||||
*/
|
||||
mdelay(PCIE_EN7581_RESET_TIME_MS);
|
||||
msleep(PCIE_EN7581_RESET_TIME_MS);
|
||||
|
||||
/* MAC power on and enable transaction layer clocks */
|
||||
reset_control_deassert(pcie->mac_reset);
|
||||
|
||||
pm_runtime_enable(dev);
|
||||
pm_runtime_get_sync(dev);
|
||||
|
||||
err = clk_bulk_prepare(pcie->num_clks, pcie->clks);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to prepare clock\n");
|
||||
goto err_clk_prepare;
|
||||
}
|
||||
|
||||
val = FIELD_PREP(PCIE_VAL_LN0_DOWNSTREAM, 0x47) |
|
||||
FIELD_PREP(PCIE_VAL_LN1_DOWNSTREAM, 0x47) |
|
||||
FIELD_PREP(PCIE_VAL_LN0_UPSTREAM, 0x41) |
|
||||
@ -963,19 +994,25 @@ static int mtk_pcie_en7581_power_up(struct mtk_gen3_pcie *pcie)
|
||||
FIELD_PREP(PCIE_K_FINETUNE_MAX, 0xf);
|
||||
writel_relaxed(val, pcie->base + PCIE_PIPE4_PIE8_REG);
|
||||
|
||||
err = clk_bulk_enable(pcie->num_clks, pcie->clks);
|
||||
err = clk_bulk_prepare_enable(pcie->num_clks, pcie->clks);
|
||||
if (err) {
|
||||
dev_err(dev, "failed to prepare clock\n");
|
||||
goto err_clk_enable;
|
||||
goto err_clk_prepare_enable;
|
||||
}
|
||||
|
||||
/*
|
||||
* Airoha EN7581 performs PCIe reset via clk callabacks since it has a
|
||||
* hw issue with PCIE_PE_RSTB signal. Add wait for the time needed to
|
||||
* complete the PCIe reset.
|
||||
*/
|
||||
msleep(PCIE_T_PVPERL_MS);
|
||||
|
||||
return 0;
|
||||
|
||||
err_clk_enable:
|
||||
clk_bulk_unprepare(pcie->num_clks, pcie->clks);
|
||||
err_clk_prepare:
|
||||
err_clk_prepare_enable:
|
||||
pm_runtime_put_sync(dev);
|
||||
pm_runtime_disable(dev);
|
||||
reset_control_assert(pcie->mac_reset);
|
||||
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
|
||||
err_phy_deassert:
|
||||
phy_power_off(pcie->phy);
|
||||
@ -990,6 +1027,15 @@ static int mtk_pcie_power_up(struct mtk_gen3_pcie *pcie)
|
||||
struct device *dev = pcie->dev;
|
||||
int err;
|
||||
|
||||
/*
|
||||
* The controller may have been left out of reset by the bootloader
|
||||
* so make sure that we get a clean start by asserting resets here.
|
||||
*/
|
||||
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets,
|
||||
pcie->phy_resets);
|
||||
reset_control_assert(pcie->mac_reset);
|
||||
usleep_range(PCIE_MTK_RESET_TIME_US, 2 * PCIE_MTK_RESET_TIME_US);
|
||||
|
||||
/* PHY power on and enable pipe clock */
|
||||
err = reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
|
||||
if (err) {
|
||||
@ -1074,14 +1120,6 @@ static int mtk_pcie_setup(struct mtk_gen3_pcie *pcie)
|
||||
* counter since the bulk is shared.
|
||||
*/
|
||||
reset_control_bulk_deassert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
|
||||
/*
|
||||
* The controller may have been left out of reset by the bootloader
|
||||
* so make sure that we get a clean start by asserting resets here.
|
||||
*/
|
||||
reset_control_bulk_assert(pcie->soc->phy_resets.num_resets, pcie->phy_resets);
|
||||
|
||||
reset_control_assert(pcie->mac_reset);
|
||||
usleep_range(10, 20);
|
||||
|
||||
/* Don't touch the hardware registers before power up */
|
||||
err = pcie->soc->power_up(pcie);
|
||||
@ -1231,10 +1269,12 @@ static int mtk_pcie_suspend_noirq(struct device *dev)
|
||||
return err;
|
||||
}
|
||||
|
||||
/* Pull down the PERST# pin */
|
||||
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
|
||||
val |= PCIE_PE_RSTB;
|
||||
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
if (!(pcie->soc->flags & SKIP_PCIE_RSTB)) {
|
||||
/* Pull down the PERST# pin */
|
||||
val = readl_relaxed(pcie->base + PCIE_RST_CTRL_REG);
|
||||
val |= PCIE_PE_RSTB;
|
||||
writel_relaxed(val, pcie->base + PCIE_RST_CTRL_REG);
|
||||
}
|
||||
|
||||
dev_dbg(pcie->dev, "entered L2 states successfully");
|
||||
|
||||
@ -1285,6 +1325,7 @@ static const struct mtk_gen3_pcie_pdata mtk_pcie_soc_en7581 = {
|
||||
.id[2] = "phy-lane2",
|
||||
.num_resets = 3,
|
||||
},
|
||||
.flags = SKIP_PCIE_RSTB,
|
||||
};
|
||||
|
||||
static const struct of_device_id mtk_pcie_of_match[] = {
|
||||
|
Loading…
Reference in New Issue
Block a user