Skip to content

Commit 5223084

Browse files
nxpfranklikwilczynski
authored andcommitted
PCI: imx6: Simplify switch-case logic by involve core_reset callback
Instead of using the switch case statement to assert/dassert the core reset handled by this driver itself, let's introduce a new callback core_reset() and define it for platforms that require it. This simplifies the code. Link: https://lore.kernel.org/linux-pci/[email protected] Signed-off-by: Frank Li <[email protected]> [kwilczynski: commit log] Signed-off-by: Krzysztof Wilczyński <[email protected]> Reviewed-by: Manivannan Sadhasivam <[email protected]>
1 parent 256867b commit 5223084

File tree

1 file changed

+71
-63
lines changed

1 file changed

+71
-63
lines changed

drivers/pci/controller/dwc/pci-imx6.c

Lines changed: 71 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,7 @@ struct imx_pcie_drvdata {
102102
const struct pci_epc_features *epc_features;
103103
int (*init_phy)(struct imx_pcie *pcie);
104104
int (*enable_ref_clk)(struct imx_pcie *pcie, bool enable);
105+
int (*core_reset)(struct imx_pcie *pcie, bool assert);
105106
};
106107

107108
struct imx_pcie {
@@ -668,83 +669,86 @@ static void imx_pcie_clk_disable(struct imx_pcie *imx_pcie)
668669
clk_bulk_disable_unprepare(imx_pcie->drvdata->clks_cnt, imx_pcie->clks);
669670
}
670671

672+
static int imx6sx_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
673+
{
674+
if (assert)
675+
regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
676+
IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
677+
678+
/* Force PCIe PHY reset */
679+
regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5, IMX6SX_GPR5_PCIE_BTNRST_RESET,
680+
assert ? IMX6SX_GPR5_PCIE_BTNRST_RESET : 0);
681+
return 0;
682+
}
683+
684+
static int imx6qp_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
685+
{
686+
regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_SW_RST,
687+
assert ? IMX6Q_GPR1_PCIE_SW_RST : 0);
688+
if (!assert)
689+
usleep_range(200, 500);
690+
691+
return 0;
692+
}
693+
694+
static int imx6q_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
695+
{
696+
if (!assert)
697+
return 0;
698+
699+
regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_TEST_PD);
700+
regmap_set_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1, IMX6Q_GPR1_PCIE_REF_CLK_EN);
701+
702+
return 0;
703+
}
704+
705+
static int imx7d_pcie_core_reset(struct imx_pcie *imx_pcie, bool assert)
706+
{
707+
struct dw_pcie *pci = imx_pcie->pci;
708+
struct device *dev = pci->dev;
709+
710+
if (assert)
711+
return 0;
712+
713+
/*
714+
* Workaround for ERR010728, failure of PCI-e PLL VCO to
715+
* oscillate, especially when cold. This turns off "Duty-cycle
716+
* Corrector" and other mysterious undocumented things.
717+
*/
718+
719+
if (likely(imx_pcie->phy_base)) {
720+
/* De-assert DCC_FB_EN */
721+
writel(PCIE_PHY_CMN_REG4_DCC_FB_EN, imx_pcie->phy_base + PCIE_PHY_CMN_REG4);
722+
/* Assert RX_EQS and RX_EQS_SEL */
723+
writel(PCIE_PHY_CMN_REG24_RX_EQ_SEL | PCIE_PHY_CMN_REG24_RX_EQ,
724+
imx_pcie->phy_base + PCIE_PHY_CMN_REG24);
725+
/* Assert ATT_MODE */
726+
writel(PCIE_PHY_CMN_REG26_ATT_MODE, imx_pcie->phy_base + PCIE_PHY_CMN_REG26);
727+
} else {
728+
dev_warn(dev, "Unable to apply ERR010728 workaround. DT missing fsl,imx7d-pcie-phy phandle ?\n");
729+
}
730+
imx7d_pcie_wait_for_phy_pll_lock(imx_pcie);
731+
return 0;
732+
}
733+
671734
static void imx_pcie_assert_core_reset(struct imx_pcie *imx_pcie)
672735
{
673736
reset_control_assert(imx_pcie->pciephy_reset);
674737
reset_control_assert(imx_pcie->apps_reset);
675738

676-
switch (imx_pcie->drvdata->variant) {
677-
case IMX6SX:
678-
regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR12,
679-
IMX6SX_GPR12_PCIE_TEST_POWERDOWN,
680-
IMX6SX_GPR12_PCIE_TEST_POWERDOWN);
681-
/* Force PCIe PHY reset */
682-
regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5,
683-
IMX6SX_GPR5_PCIE_BTNRST_RESET,
684-
IMX6SX_GPR5_PCIE_BTNRST_RESET);
685-
break;
686-
case IMX6QP:
687-
regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
688-
IMX6Q_GPR1_PCIE_SW_RST,
689-
IMX6Q_GPR1_PCIE_SW_RST);
690-
break;
691-
case IMX6Q:
692-
regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
693-
IMX6Q_GPR1_PCIE_TEST_PD, 1 << 18);
694-
regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
695-
IMX6Q_GPR1_PCIE_REF_CLK_EN, 0 << 16);
696-
break;
697-
default:
698-
break;
699-
}
739+
if (imx_pcie->drvdata->core_reset)
740+
imx_pcie->drvdata->core_reset(imx_pcie, true);
700741

701742
/* Some boards don't have PCIe reset GPIO. */
702743
gpiod_set_value_cansleep(imx_pcie->reset_gpiod, 1);
703744
}
704745

705746
static int imx_pcie_deassert_core_reset(struct imx_pcie *imx_pcie)
706747
{
707-
struct dw_pcie *pci = imx_pcie->pci;
708-
struct device *dev = pci->dev;
709-
710748
reset_control_deassert(imx_pcie->pciephy_reset);
711749

712-
switch (imx_pcie->drvdata->variant) {
713-
case IMX7D:
714-
/* Workaround for ERR010728, failure of PCI-e PLL VCO to
715-
* oscillate, especially when cold. This turns off "Duty-cycle
716-
* Corrector" and other mysterious undocumented things.
717-
*/
718-
if (likely(imx_pcie->phy_base)) {
719-
/* De-assert DCC_FB_EN */
720-
writel(PCIE_PHY_CMN_REG4_DCC_FB_EN,
721-
imx_pcie->phy_base + PCIE_PHY_CMN_REG4);
722-
/* Assert RX_EQS and RX_EQS_SEL */
723-
writel(PCIE_PHY_CMN_REG24_RX_EQ_SEL
724-
| PCIE_PHY_CMN_REG24_RX_EQ,
725-
imx_pcie->phy_base + PCIE_PHY_CMN_REG24);
726-
/* Assert ATT_MODE */
727-
writel(PCIE_PHY_CMN_REG26_ATT_MODE,
728-
imx_pcie->phy_base + PCIE_PHY_CMN_REG26);
729-
} else {
730-
dev_warn(dev, "Unable to apply ERR010728 workaround. DT missing fsl,imx7d-pcie-phy phandle ?\n");
731-
}
732-
733-
imx7d_pcie_wait_for_phy_pll_lock(imx_pcie);
734-
break;
735-
case IMX6SX:
736-
regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR5,
737-
IMX6SX_GPR5_PCIE_BTNRST_RESET, 0);
738-
break;
739-
case IMX6QP:
740-
regmap_update_bits(imx_pcie->iomuxc_gpr, IOMUXC_GPR1,
741-
IMX6Q_GPR1_PCIE_SW_RST, 0);
742-
743-
usleep_range(200, 500);
744-
break;
745-
default:
746-
break;
747-
}
750+
if (imx_pcie->drvdata->core_reset)
751+
imx_pcie->drvdata->core_reset(imx_pcie, false);
748752

749753
/* Some boards don't have PCIe reset GPIO. */
750754
if (imx_pcie->reset_gpiod) {
@@ -1441,6 +1445,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
14411445
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
14421446
.init_phy = imx_pcie_init_phy,
14431447
.enable_ref_clk = imx6q_pcie_enable_ref_clk,
1448+
.core_reset = imx6q_pcie_core_reset,
14441449
},
14451450
[IMX6SX] = {
14461451
.variant = IMX6SX,
@@ -1456,6 +1461,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
14561461
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
14571462
.init_phy = imx6sx_pcie_init_phy,
14581463
.enable_ref_clk = imx6sx_pcie_enable_ref_clk,
1464+
.core_reset = imx6sx_pcie_core_reset,
14591465
},
14601466
[IMX6QP] = {
14611467
.variant = IMX6QP,
@@ -1472,6 +1478,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
14721478
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
14731479
.init_phy = imx_pcie_init_phy,
14741480
.enable_ref_clk = imx6q_pcie_enable_ref_clk,
1481+
.core_reset = imx6qp_pcie_core_reset,
14751482
},
14761483
[IMX7D] = {
14771484
.variant = IMX7D,
@@ -1485,6 +1492,7 @@ static const struct imx_pcie_drvdata drvdata[] = {
14851492
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
14861493
.init_phy = imx7d_pcie_init_phy,
14871494
.enable_ref_clk = imx7d_pcie_enable_ref_clk,
1495+
.core_reset = imx7d_pcie_core_reset,
14881496
},
14891497
[IMX8MQ] = {
14901498
.variant = IMX8MQ,

0 commit comments

Comments
 (0)