> -----Original Message----- > From: Bjorn Helgaas <helgaas@xxxxxxxxxx> > Sent: 2022年6月16日 7:16 > To: Hongxing Zhu <hongxing.zhu@xxxxxxx>; Lucas Stach > <l.stach@xxxxxxxxxxxxxx>; Rob Herring <robh+dt@xxxxxxxxxx>; Mark Brown > <broonie@xxxxxxxxxx>; Lorenzo Pieralisi <lorenzo.pieralisi@xxxxxxx>; Fabio > Estevam <festevam@xxxxxxxxx>; Francesco Dolcini > <francesco.dolcini@xxxxxxxxxxx> > Cc: linux-pci@xxxxxxxxxxxxxxx; linux-arm-kernel@xxxxxxxxxxxxxxxxxxx; > linux-kernel@xxxxxxxxxxxxxxx; kernel@xxxxxxxxxxxxxx; dl-linux-imx > <linux-imx@xxxxxxx>; Bjorn Helgaas <bhelgaas@xxxxxxxxxx> > Subject: [PATCH v12 02/13] PCI: imx6: Move PHY management functions > together > > From: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> > > Collect imx6_pcie_init_phy(), imx7d_pcie_wait_for_phy_pll_lock(), and > imx6_setup_phy_mpll() earlier with other PHY-related code. No functional > change intended. > > Signed-off-by: Bjorn Helgaas <bhelgaas@xxxxxxxxxx> Acked-by: Richard Zhu <hongxing.zhu@xxxxxxx> Best Regards Richard Zhu > --- > drivers/pci/controller/dwc/pci-imx6.c | 256 +++++++++++++------------- > 1 file changed, 128 insertions(+), 128 deletions(-) > > diff --git a/drivers/pci/controller/dwc/pci-imx6.c > b/drivers/pci/controller/dwc/pci-imx6.c > index 8653ca8cbfb9..e63eb6380020 100644 > --- a/drivers/pci/controller/dwc/pci-imx6.c > +++ b/drivers/pci/controller/dwc/pci-imx6.c > @@ -296,6 +296,134 @@ static int pcie_phy_write(struct imx6_pcie > *imx6_pcie, int addr, u16 data) > return 0; > } > > +static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) { > + switch (imx6_pcie->drvdata->variant) { > + case IMX8MM: > + /* > + * The PHY initialization had been done in the PHY > + * driver, break here directly. > + */ > + break; > + case IMX8MQ: > + /* > + * TODO: Currently this code assumes external > + * oscillator is being used > + */ > + regmap_update_bits(imx6_pcie->iomuxc_gpr, > + imx6_pcie_grp_offset(imx6_pcie), > + IMX8MQ_GPR_PCIE_REF_USE_PAD, > + IMX8MQ_GPR_PCIE_REF_USE_PAD); > + /* > + * Regarding the datasheet, the PCIE_VPH is suggested > + * to be 1.8V. If the PCIE_VPH is supplied by 3.3V, the > + * VREG_BYPASS should be cleared to zero. > + */ > + if (imx6_pcie->vph && > + regulator_get_voltage(imx6_pcie->vph) > 3000000) > + regmap_update_bits(imx6_pcie->iomuxc_gpr, > + imx6_pcie_grp_offset(imx6_pcie), > + IMX8MQ_GPR_PCIE_VREG_BYPASS, > + 0); > + break; > + case IMX7D: > + 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); > + > + /* configure constant input signal to the pcie ctrl and phy */ > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > + IMX6Q_GPR12_LOS_LEVEL, 9 << 4); > + > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > + IMX6Q_GPR8_TX_DEEMPH_GEN1, > + imx6_pcie->tx_deemph_gen1 << 0); > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > + IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB, > + imx6_pcie->tx_deemph_gen2_3p5db << 6); > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > + IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB, > + imx6_pcie->tx_deemph_gen2_6db << 12); > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > + IMX6Q_GPR8_TX_SWING_FULL, > + imx6_pcie->tx_swing_full << 18); > + regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > + IMX6Q_GPR8_TX_SWING_LOW, > + imx6_pcie->tx_swing_low << 25); > + break; > + } > + > + imx6_pcie_configure_type(imx6_pcie); > +} > + > +static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie > +*imx6_pcie) { > + u32 val; > + struct device *dev = imx6_pcie->pci->dev; > + > + if (regmap_read_poll_timeout(imx6_pcie->iomuxc_gpr, > + IOMUXC_GPR22, val, > + val & IMX7D_GPR22_PCIE_PHY_PLL_LOCKED, > + PHY_PLL_LOCK_WAIT_USLEEP_MAX, > + PHY_PLL_LOCK_WAIT_TIMEOUT)) > + dev_err(dev, "PCIe PLL lock timeout\n"); } > + > +static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) { > + unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy); > + int mult, div; > + u16 val; > + > + if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) > + return 0; > + > + switch (phy_rate) { > + case 125000000: > + /* > + * The default settings of the MPLL are for a 125MHz input > + * clock, so no need to reconfigure anything in that case. > + */ > + return 0; > + case 100000000: > + mult = 25; > + div = 0; > + break; > + case 200000000: > + mult = 25; > + div = 1; > + break; > + default: > + dev_err(imx6_pcie->pci->dev, > + "Unsupported PHY reference clock rate %lu\n", phy_rate); > + return -EINVAL; > + } > + > + pcie_phy_read(imx6_pcie, PCIE_PHY_MPLL_OVRD_IN_LO, &val); > + val &= ~(PCIE_PHY_MPLL_MULTIPLIER_MASK << > + PCIE_PHY_MPLL_MULTIPLIER_SHIFT); > + val |= mult << PCIE_PHY_MPLL_MULTIPLIER_SHIFT; > + val |= PCIE_PHY_MPLL_MULTIPLIER_OVRD; > + pcie_phy_write(imx6_pcie, PCIE_PHY_MPLL_OVRD_IN_LO, val); > + > + pcie_phy_read(imx6_pcie, PCIE_PHY_ATEOVRD, &val); > + val &= ~(PCIE_PHY_ATEOVRD_REF_CLKDIV_MASK << > + PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT); > + val |= div << PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT; > + val |= PCIE_PHY_ATEOVRD_EN; > + pcie_phy_write(imx6_pcie, PCIE_PHY_ATEOVRD, val); > + > + return 0; > +} > + > static void imx6_pcie_reset_phy(struct imx6_pcie *imx6_pcie) { > u16 tmp; > @@ -500,19 +628,6 @@ static int imx6_pcie_enable_ref_clk(struct imx6_pcie > *imx6_pcie) > return ret; > } > > -static void imx7d_pcie_wait_for_phy_pll_lock(struct imx6_pcie *imx6_pcie) -{ > - u32 val; > - struct device *dev = imx6_pcie->pci->dev; > - > - if (regmap_read_poll_timeout(imx6_pcie->iomuxc_gpr, > - IOMUXC_GPR22, val, > - val & IMX7D_GPR22_PCIE_PHY_PLL_LOCKED, > - PHY_PLL_LOCK_WAIT_USLEEP_MAX, > - PHY_PLL_LOCK_WAIT_TIMEOUT)) > - dev_err(dev, "PCIe PLL lock timeout\n"); > -} > - > static void imx6_pcie_deassert_core_reset(struct imx6_pcie *imx6_pcie) { > struct dw_pcie *pci = imx6_pcie->pci; > @@ -635,121 +750,6 @@ static void imx6_pcie_deassert_core_reset(struct > imx6_pcie *imx6_pcie) > } > } > > -static void imx6_pcie_init_phy(struct imx6_pcie *imx6_pcie) -{ > - switch (imx6_pcie->drvdata->variant) { > - case IMX8MM: > - /* > - * The PHY initialization had been done in the PHY > - * driver, break here directly. > - */ > - break; > - case IMX8MQ: > - /* > - * TODO: Currently this code assumes external > - * oscillator is being used > - */ > - regmap_update_bits(imx6_pcie->iomuxc_gpr, > - imx6_pcie_grp_offset(imx6_pcie), > - IMX8MQ_GPR_PCIE_REF_USE_PAD, > - IMX8MQ_GPR_PCIE_REF_USE_PAD); > - /* > - * Regarding the datasheet, the PCIE_VPH is suggested > - * to be 1.8V. If the PCIE_VPH is supplied by 3.3V, the > - * VREG_BYPASS should be cleared to zero. > - */ > - if (imx6_pcie->vph && > - regulator_get_voltage(imx6_pcie->vph) > 3000000) > - regmap_update_bits(imx6_pcie->iomuxc_gpr, > - imx6_pcie_grp_offset(imx6_pcie), > - IMX8MQ_GPR_PCIE_VREG_BYPASS, > - 0); > - break; > - case IMX7D: > - 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); > - > - /* configure constant input signal to the pcie ctrl and phy */ > - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR12, > - IMX6Q_GPR12_LOS_LEVEL, 9 << 4); > - > - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > - IMX6Q_GPR8_TX_DEEMPH_GEN1, > - imx6_pcie->tx_deemph_gen1 << 0); > - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > - IMX6Q_GPR8_TX_DEEMPH_GEN2_3P5DB, > - imx6_pcie->tx_deemph_gen2_3p5db << 6); > - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > - IMX6Q_GPR8_TX_DEEMPH_GEN2_6DB, > - imx6_pcie->tx_deemph_gen2_6db << 12); > - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > - IMX6Q_GPR8_TX_SWING_FULL, > - imx6_pcie->tx_swing_full << 18); > - regmap_update_bits(imx6_pcie->iomuxc_gpr, IOMUXC_GPR8, > - IMX6Q_GPR8_TX_SWING_LOW, > - imx6_pcie->tx_swing_low << 25); > - break; > - } > - > - imx6_pcie_configure_type(imx6_pcie); > -} > - > -static int imx6_setup_phy_mpll(struct imx6_pcie *imx6_pcie) -{ > - unsigned long phy_rate = clk_get_rate(imx6_pcie->pcie_phy); > - int mult, div; > - u16 val; > - > - if (!(imx6_pcie->drvdata->flags & IMX6_PCIE_FLAG_IMX6_PHY)) > - return 0; > - > - switch (phy_rate) { > - case 125000000: > - /* > - * The default settings of the MPLL are for a 125MHz input > - * clock, so no need to reconfigure anything in that case. > - */ > - return 0; > - case 100000000: > - mult = 25; > - div = 0; > - break; > - case 200000000: > - mult = 25; > - div = 1; > - break; > - default: > - dev_err(imx6_pcie->pci->dev, > - "Unsupported PHY reference clock rate %lu\n", phy_rate); > - return -EINVAL; > - } > - > - pcie_phy_read(imx6_pcie, PCIE_PHY_MPLL_OVRD_IN_LO, &val); > - val &= ~(PCIE_PHY_MPLL_MULTIPLIER_MASK << > - PCIE_PHY_MPLL_MULTIPLIER_SHIFT); > - val |= mult << PCIE_PHY_MPLL_MULTIPLIER_SHIFT; > - val |= PCIE_PHY_MPLL_MULTIPLIER_OVRD; > - pcie_phy_write(imx6_pcie, PCIE_PHY_MPLL_OVRD_IN_LO, val); > - > - pcie_phy_read(imx6_pcie, PCIE_PHY_ATEOVRD, &val); > - val &= ~(PCIE_PHY_ATEOVRD_REF_CLKDIV_MASK << > - PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT); > - val |= div << PCIE_PHY_ATEOVRD_REF_CLKDIV_SHIFT; > - val |= PCIE_PHY_ATEOVRD_EN; > - pcie_phy_write(imx6_pcie, PCIE_PHY_ATEOVRD, val); > - > - return 0; > -} > - > static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie) { > struct dw_pcie *pci = imx6_pcie->pci; > -- > 2.25.1