drivers: pci: imx: fix imx_pcie_remove function
We have at least a minor count of boards, that failed to re-initialize
PCI express in the Linux kernel. Typical failure rate is 20% on affected
boards. This is mitigated by commit 6ecbe13756
("drivers: pci: imx:
add imx_pcie_remove function").
However, at least on some i.MX6 custom boards, when calling
assert_core_reset() as part of the first-time PCIe init, read access
to PCIE_PL_PFLR simply hangs. Surround this readl() with
imx_pcie_fix_dabt_handler() does not help. For this reason, the forced
LTSSM detection is only used on the second assert_core_reset() that is
called shorly before starting the Linux kernel.
Signed-off-by: Sven-Ola Tuecke <sven-ola.tuecke@numberfour.eu>
Signed-off-by: Fabio Estevam <fabio.estevam@nxp.com>
Tested-by: David Müller <d.mueller@elsoft.ch>
This commit is contained in:
parent
066d97c733
commit
b2915ba25e
@ -431,7 +431,7 @@ static int imx_pcie_write_config(struct pci_controller *hose, pci_dev_t d,
|
|||||||
/*
|
/*
|
||||||
* Initial bus setup
|
* Initial bus setup
|
||||||
*/
|
*/
|
||||||
static int imx6_pcie_assert_core_reset(void)
|
static int imx6_pcie_assert_core_reset(bool prepare_for_boot)
|
||||||
{
|
{
|
||||||
struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
|
struct iomuxc *iomuxc_regs = (struct iomuxc *)IOMUXC_BASE_ADDR;
|
||||||
|
|
||||||
@ -459,7 +459,7 @@ static int imx6_pcie_assert_core_reset(void)
|
|||||||
* If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong
|
* If both LTSSM_ENABLE and REF_SSP_ENABLE are active we have a strong
|
||||||
* indication that the bootloader activated the link.
|
* indication that the bootloader activated the link.
|
||||||
*/
|
*/
|
||||||
if (is_mx6dq()) {
|
if (is_mx6dq() && prepare_for_boot) {
|
||||||
u32 val, gpr1, gpr12;
|
u32 val, gpr1, gpr12;
|
||||||
|
|
||||||
gpr1 = readl(&iomuxc_regs->gpr[1]);
|
gpr1 = readl(&iomuxc_regs->gpr[1]);
|
||||||
@ -605,7 +605,7 @@ static int imx_pcie_link_up(void)
|
|||||||
uint32_t tmp;
|
uint32_t tmp;
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
imx6_pcie_assert_core_reset();
|
imx6_pcie_assert_core_reset(false);
|
||||||
imx6_pcie_init_phy();
|
imx6_pcie_init_phy();
|
||||||
imx6_pcie_deassert_core_reset();
|
imx6_pcie_deassert_core_reset();
|
||||||
|
|
||||||
@ -687,7 +687,7 @@ void imx_pcie_init(void)
|
|||||||
|
|
||||||
void imx_pcie_remove(void)
|
void imx_pcie_remove(void)
|
||||||
{
|
{
|
||||||
imx6_pcie_assert_core_reset();
|
imx6_pcie_assert_core_reset(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Probe function. */
|
/* Probe function. */
|
||||||
|
Loading…
Reference in New Issue
Block a user