Commit 21ad80b0 authored by Frank Li's avatar Frank Li Committed by Lorenzo Pieralisi

PCI: imx6: Simplify switch-case logic by introducing init_phy() callback

Instead of using the switch case statement to initialize the PHY handled by
this driver itself, let's introduce a new callback init_phy() and define it
for platforms that require it.

Link: https://lore.kernel.org/r/20240220161924.3871774-7-Frank.Li@nxp.comSigned-off-by: default avatarFrank Li <Frank.Li@nxp.com>
Signed-off-by: default avatarLorenzo Pieralisi <lpieralisi@kernel.org>
Reviewed-by: default avatarManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
parent f99b121c
...@@ -69,6 +69,9 @@ enum imx6_pcie_variants { ...@@ -69,6 +69,9 @@ enum imx6_pcie_variants {
#define IMX6_PCIE_MAX_CLKS 6 #define IMX6_PCIE_MAX_CLKS 6
#define IMX6_PCIE_MAX_INSTANCES 2 #define IMX6_PCIE_MAX_INSTANCES 2
struct imx6_pcie;
struct imx6_pcie_drvdata { struct imx6_pcie_drvdata {
enum imx6_pcie_variants variant; enum imx6_pcie_variants variant;
enum dw_pcie_device_mode mode; enum dw_pcie_device_mode mode;
...@@ -81,6 +84,7 @@ struct imx6_pcie_drvdata { ...@@ -81,6 +84,7 @@ struct imx6_pcie_drvdata {
const u32 ltssm_mask; const u32 ltssm_mask;
const u32 mode_off[IMX6_PCIE_MAX_INSTANCES]; const u32 mode_off[IMX6_PCIE_MAX_INSTANCES];
const u32 mode_mask[IMX6_PCIE_MAX_INSTANCES]; const u32 mode_mask[IMX6_PCIE_MAX_INSTANCES];
int (*init_phy)(struct imx6_pcie *pcie);
}; };
struct imx6_pcie { struct imx6_pcie {
...@@ -322,76 +326,66 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data) ...@@ -322,76 +326,66 @@ static int pcie_phy_write(struct imx6_pcie *imx6_pcie, int addr, u16 data)
return 0; return 0;
} }
static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) static int imx8mq_pcie_init_phy(struct imx6_pcie *imx6_pcie)
{ {
switch (imx6_pcie->drvdata->variant) { /* TODO: Currently this code assumes external oscillator is being used */
case IMX8MM: regmap_update_bits(imx6_pcie->iomuxc_gpr,
case IMX8MM_EP: imx6_pcie_grp_offset(imx6_pcie),
case IMX8MP: IMX8MQ_GPR_PCIE_REF_USE_PAD,
case IMX8MP_EP: IMX8MQ_GPR_PCIE_REF_USE_PAD);
/* /*
* The PHY initialization had been done in the PHY * Regarding the datasheet, the PCIE_VPH is suggested to be 1.8V. If the PCIE_VPH is
* driver, break here directly. * supplied by 3.3V, the VREG_BYPASS should be cleared to zero.
*/ */
break; if (imx6_pcie->vph && regulator_get_voltage(imx6_pcie->vph) > 3000000)
case IMX8MQ:
case IMX8MQ_EP:
/*
* TODO: Currently this code assumes external
* oscillator is being used
*/
regmap_update_bits(imx6_pcie->iomuxc_gpr, regmap_update_bits(imx6_pcie->iomuxc_gpr,
imx6_pcie_grp_offset(imx6_pcie), imx6_pcie_grp_offset(imx6_pcie),
IMX8MQ_GPR_PCIE_REF_USE_PAD, IMX8MQ_GPR_PCIE_VREG_BYPASS,
IMX8MQ_GPR_PCIE_REF_USE_PAD); 0);
/*
* Regarding the datasheet, the PCIE_VPH is suggested return 0;
* to be 1.8V. If the PCIE_VPH is supplied by 3.3V, the }
* VREG_BYPASS should be cleared to zero.
*/ static int imx7d_pcie_init_phy(struct imx6_pcie *imx6_pcie)
if (imx6_pcie->vph && {
regulator_get_voltage(imx6_pcie->vph) > 3000000) regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
regmap_update_bits(imx6_pcie->iomuxc_gpr,
imx6_pcie_grp_offset(imx6_pcie), return 0;
IMX8MQ_GPR_PCIE_VREG_BYPASS, }
0);
break; static int imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie)
case IMX7D: {
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX7D_GPR12_PCIE_PHY_REFCLK_SEL, 0);
break;
case IMX6SX:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_RX_EQ_MASK,
IMX6SX_GPR12_PCIE_RX_EQ_2);
fallthrough;
default:
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6Q_GPR12_PCIE_CTL_2, 0 << 10); IMX6Q_GPR12_PCIE_CTL_2, 0 << 10);
/* configure constant input signal to the pcie ctrl and phy */ /* configure constant input signal to the pcie ctrl and phy */
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6Q_GPR12_LOS_LEVEL, 9 << 4); IMX6Q_GPR12_LOS_LEVEL, 9 << 4);
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_DEEMPH_GEN1, IMX6Q_GPR8_TX_DEEMPH_GEN1,
imx6_pcie->tx_deemph_gen1 << 0); imx6_pcie->tx_deemph_gen1 << 0);
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB, IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB,
imx6_pcie->tx_deemph_gen2_3p5db << 6); imx6_pcie->tx_deemph_gen2_3p5db << 6);
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB, IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB,
imx6_pcie->tx_deemph_gen2_6db << 12); imx6_pcie->tx_deemph_gen2_6db << 12);
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_SWING_FULL, IMX6Q_GPR8_TX_SWING_FULL,
imx6_pcie->tx_swing_full << 18); imx6_pcie->tx_swing_full << 18);
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8,
IMX6Q_GPR8_TX_SWING_LOW, IMX6Q_GPR8_TX_SWING_LOW,
imx6_pcie->tx_swing_low << 25); imx6_pcie->tx_swing_low << 25);
break; return 0;
} }
imx6_pcie_configure_type(imx6_pcie); static int imx6sx_pcie_init_phy(struct imx6_pcie *imx6_pcie)
{
regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12,
IMX6SX_GPR12_PCIE_RX_EQ_MASK, IMX6SX_GPR12_PCIE_RX_EQ_2);
return imx6_pcie_init_phy(imx6_pcie);
} }
static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie) static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie)
...@@ -902,7 +896,11 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp) ...@@ -902,7 +896,11 @@ static int imx6_pcie_host_init(struct dw_pcie_rp *pp)
} }
imx6_pcie_assert_core_reset(imx6_pcie); imx6_pcie_assert_core_reset(imx6_pcie);
imx6_pcie_init_phy(imx6_pcie);
if (imx6_pcie->drvdata->init_phy)
imx6_pcie->drvdata->init_phy(imx6_pcie);
imx6_pcie_configure_type(imx6_pcie);
ret = imx6_pcie_clk_enable(imx6_pcie); ret = imx6_pcie_clk_enable(imx6_pcie);
if (ret) { if (ret) {
...@@ -1381,6 +1379,7 @@ static const struct imx6_pcie_drvdata drvdata[] = { ...@@ -1381,6 +1379,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2, .ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
.mode_off[0] = IOMUXC_GPR12, .mode_off[0] = IOMUXC_GPR12,
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE, .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
.init_phy = imx6_pcie_init_phy,
}, },
[IMX6SX] = { [IMX6SX] = {
.variant = IMX6SX, .variant = IMX6SX,
...@@ -1394,6 +1393,7 @@ static const struct imx6_pcie_drvdata drvdata[] = { ...@@ -1394,6 +1393,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2, .ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
.mode_off[0] = IOMUXC_GPR12, .mode_off[0] = IOMUXC_GPR12,
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE, .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
.init_phy = imx6sx_pcie_init_phy,
}, },
[IMX6QP] = { [IMX6QP] = {
.variant = IMX6QP, .variant = IMX6QP,
...@@ -1408,6 +1408,7 @@ static const struct imx6_pcie_drvdata drvdata[] = { ...@@ -1408,6 +1408,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
.ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2, .ltssm_mask = IMX6Q_GPR12_PCIE_CTL_2,
.mode_off[0] = IOMUXC_GPR12, .mode_off[0] = IOMUXC_GPR12,
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE, .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
.init_phy = imx6_pcie_init_phy,
}, },
[IMX7D] = { [IMX7D] = {
.variant = IMX7D, .variant = IMX7D,
...@@ -1419,6 +1420,7 @@ static const struct imx6_pcie_drvdata drvdata[] = { ...@@ -1419,6 +1420,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
.clks_cnt = ARRAY_SIZE(imx6q_clks), .clks_cnt = ARRAY_SIZE(imx6q_clks),
.mode_off[0] = IOMUXC_GPR12, .mode_off[0] = IOMUXC_GPR12,
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE, .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
.init_phy = imx7d_pcie_init_phy,
}, },
[IMX8MQ] = { [IMX8MQ] = {
.variant = IMX8MQ, .variant = IMX8MQ,
...@@ -1431,6 +1433,7 @@ static const struct imx6_pcie_drvdata drvdata[] = { ...@@ -1431,6 +1433,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE, .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
.mode_off[1] = IOMUXC_GPR12, .mode_off[1] = IOMUXC_GPR12,
.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, .mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
.init_phy = imx8mq_pcie_init_phy,
}, },
[IMX8MM] = { [IMX8MM] = {
.variant = IMX8MM, .variant = IMX8MM,
...@@ -1466,6 +1469,7 @@ static const struct imx6_pcie_drvdata drvdata[] = { ...@@ -1466,6 +1469,7 @@ static const struct imx6_pcie_drvdata drvdata[] = {
.mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE, .mode_mask[0] = IMX6Q_GPR12_DEVICE_TYPE,
.mode_off[1] = IOMUXC_GPR12, .mode_off[1] = IOMUXC_GPR12,
.mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE, .mode_mask[1] = IMX8MQ_GPR12_PCIE2_CTRL_DEVICE_TYPE,
.init_phy = imx8mq_pcie_init_phy,
}, },
[IMX8MM_EP] = { [IMX8MM_EP] = {
.variant = IMX8MM_EP, .variant = IMX8MM_EP,
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment