Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 199ff141 authored by Ray Jui's avatar Ray Jui Committed by Bjorn Helgaas
Browse files

PCI: iproc: Fix PCIe reset logic



The current reset logic does not always properly reset the device.  For
example, in the case when the perst_b signal is already de-asserted in the
bootloader, the current reset logic fails to trigger a proper assert ->
de-assert reset sequence.

Fix the issue by always triggering the proper reset sequence.

Also explicitly select the desired reset source, i.e., perst_b, and reduce
the wait time after the device comes out of reset from 250 ms to 100 ms,
based on recommendation from the ASIC team.

Tested-by: default avatarVladimir Dreizin <vdreizin@broadcom.com>
Tested-by: default avatarDarren Edamura <dedamura@broadcom.com>
Signed-off-by: default avatarRay Jui <rjui@broadcom.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarVladimir Dreizin <vdreizin@broadcom.com>
Reviewed-by: default avatarTrac Hoang <trhoang@broadcom.com>
Reviewed-by: default avatarScott Branden <sbranden@broadcom.com>
parent bdb8a184
Loading
Loading
Loading
Loading
+10 −5
Original line number Diff line number Diff line
@@ -31,6 +31,8 @@
#include "pcie-iproc.h"

#define CLK_CONTROL_OFFSET           0x000
#define EP_PERST_SOURCE_SELECT_SHIFT 2
#define EP_PERST_SOURCE_SELECT       BIT(EP_PERST_SOURCE_SELECT_SHIFT)
#define EP_MODE_SURVIVE_PERST_SHIFT  1
#define EP_MODE_SURVIVE_PERST        BIT(EP_MODE_SURVIVE_PERST_SHIFT)
#define RC_PCIE_RST_OUTPUT_SHIFT     0
@@ -119,15 +121,18 @@ static void iproc_pcie_reset(struct iproc_pcie *pcie)
	u32 val;

	/*
	 * Configure the PCIe controller as root complex and send a downstream
	 * reset
	 * Select perst_b signal as reset source. Put the device into reset,
	 * and then bring it out of reset
	 */
	val = EP_MODE_SURVIVE_PERST | RC_PCIE_RST_OUTPUT;
	val = readl(pcie->base + CLK_CONTROL_OFFSET);
	val &= ~EP_PERST_SOURCE_SELECT & ~EP_MODE_SURVIVE_PERST &
		~RC_PCIE_RST_OUTPUT;
	writel(val, pcie->base + CLK_CONTROL_OFFSET);
	udelay(250);
	val &= ~EP_MODE_SURVIVE_PERST;

	val |= RC_PCIE_RST_OUTPUT;
	writel(val, pcie->base + CLK_CONTROL_OFFSET);
	msleep(250);
	msleep(100);
}

static int iproc_pcie_check_link(struct iproc_pcie *pcie, struct pci_bus *bus)