Skip to content

Commit ca679c4

Browse files
Richard Zhuvinodkoul
authored andcommitted
phy: freescale: imx8m-pcie: Refine i.MX8MM PCIe PHY driver
To make it more flexible and easy to expand. Refine i.MX8MM PCIe PHY driver. - Use gpr compatible string to avoid the codes duplications when add another platform PCIe PHY support. - Re-arrange the codes to let it more flexible and easy to expand. No functional change. Re-arrange the TX tuning, since internal registers can be wrote through APB interface before assertion of CMN_RST. Signed-off-by: Richard Zhu <[email protected]> Signed-off-by: Lucas Stach <[email protected]> Tested-by: Marek Vasut <[email protected]> Tested-by: Richard Leitner <[email protected]> Tested-by: Alexander Stein <[email protected]> Reviewed-by: Lucas Stach <[email protected]> Reviewed-by: Ahmad Fatoum <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Vinod Koul <[email protected]>
1 parent e9e7dca commit ca679c4

File tree

1 file changed

+66
-40
lines changed

1 file changed

+66
-40
lines changed

drivers/phy/freescale/phy-fsl-imx8m-pcie.c

Lines changed: 66 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
#include <linux/mfd/syscon.h>
1212
#include <linux/mfd/syscon/imx7-iomuxc-gpr.h>
1313
#include <linux/module.h>
14+
#include <linux/of_device.h>
1415
#include <linux/phy/phy.h>
1516
#include <linux/platform_device.h>
1617
#include <linux/regmap.h>
@@ -45,6 +46,15 @@
4546
#define IMX8MM_GPR_PCIE_SSC_EN BIT(16)
4647
#define IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE BIT(9)
4748

49+
enum imx8_pcie_phy_type {
50+
IMX8MM,
51+
};
52+
53+
struct imx8_pcie_phy_drvdata {
54+
const char *gpr;
55+
enum imx8_pcie_phy_type variant;
56+
};
57+
4858
struct imx8_pcie_phy {
4959
void __iomem *base;
5060
struct clk *clk;
@@ -55,6 +65,7 @@ struct imx8_pcie_phy {
5565
u32 tx_deemph_gen1;
5666
u32 tx_deemph_gen2;
5767
bool clkreq_unused;
68+
const struct imx8_pcie_phy_drvdata *drvdata;
5869
};
5970

6071
static int imx8_pcie_phy_power_on(struct phy *phy)
@@ -66,31 +77,17 @@ static int imx8_pcie_phy_power_on(struct phy *phy)
6677
reset_control_assert(imx8_phy->reset);
6778

6879
pad_mode = imx8_phy->refclk_pad_mode;
69-
/* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't hooked */
70-
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
71-
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE,
72-
imx8_phy->clkreq_unused ?
73-
0 : IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
74-
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
75-
IMX8MM_GPR_PCIE_AUX_EN,
76-
IMX8MM_GPR_PCIE_AUX_EN);
77-
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
78-
IMX8MM_GPR_PCIE_POWER_OFF, 0);
79-
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
80-
IMX8MM_GPR_PCIE_SSC_EN, 0);
81-
82-
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
83-
IMX8MM_GPR_PCIE_REF_CLK_SEL,
84-
pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ?
85-
IMX8MM_GPR_PCIE_REF_CLK_EXT :
86-
IMX8MM_GPR_PCIE_REF_CLK_PLL);
87-
usleep_range(100, 200);
88-
89-
/* Do the PHY common block reset */
90-
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
91-
IMX8MM_GPR_PCIE_CMN_RST,
92-
IMX8MM_GPR_PCIE_CMN_RST);
93-
usleep_range(200, 500);
80+
switch (imx8_phy->drvdata->variant) {
81+
case IMX8MM:
82+
/* Tune PHY de-emphasis setting to pass PCIe compliance. */
83+
if (imx8_phy->tx_deemph_gen1)
84+
writel(imx8_phy->tx_deemph_gen1,
85+
imx8_phy->base + PCIE_PHY_TRSV_REG5);
86+
if (imx8_phy->tx_deemph_gen2)
87+
writel(imx8_phy->tx_deemph_gen2,
88+
imx8_phy->base + PCIE_PHY_TRSV_REG6);
89+
break;
90+
}
9491

9592
if (pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ||
9693
pad_mode == IMX8_PCIE_REFCLK_PAD_UNUSED) {
@@ -118,15 +115,37 @@ static int imx8_pcie_phy_power_on(struct phy *phy)
118115
imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG065);
119116
}
120117

121-
/* Tune PHY de-emphasis setting to pass PCIe compliance. */
122-
if (imx8_phy->tx_deemph_gen1)
123-
writel(imx8_phy->tx_deemph_gen1,
124-
imx8_phy->base + PCIE_PHY_TRSV_REG5);
125-
if (imx8_phy->tx_deemph_gen2)
126-
writel(imx8_phy->tx_deemph_gen2,
127-
imx8_phy->base + PCIE_PHY_TRSV_REG6);
118+
/* Set AUX_EN_OVERRIDE 1'b0, when the CLKREQ# isn't hooked */
119+
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
120+
IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE,
121+
imx8_phy->clkreq_unused ?
122+
0 : IMX8MM_GPR_PCIE_AUX_EN_OVERRIDE);
123+
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
124+
IMX8MM_GPR_PCIE_AUX_EN,
125+
IMX8MM_GPR_PCIE_AUX_EN);
126+
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
127+
IMX8MM_GPR_PCIE_POWER_OFF, 0);
128+
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
129+
IMX8MM_GPR_PCIE_SSC_EN, 0);
128130

129-
reset_control_deassert(imx8_phy->reset);
131+
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
132+
IMX8MM_GPR_PCIE_REF_CLK_SEL,
133+
pad_mode == IMX8_PCIE_REFCLK_PAD_INPUT ?
134+
IMX8MM_GPR_PCIE_REF_CLK_EXT :
135+
IMX8MM_GPR_PCIE_REF_CLK_PLL);
136+
usleep_range(100, 200);
137+
138+
/* Do the PHY common block reset */
139+
regmap_update_bits(imx8_phy->iomuxc_gpr, IOMUXC_GPR14,
140+
IMX8MM_GPR_PCIE_CMN_RST,
141+
IMX8MM_GPR_PCIE_CMN_RST);
142+
143+
switch (imx8_phy->drvdata->variant) {
144+
case IMX8MM:
145+
reset_control_deassert(imx8_phy->reset);
146+
usleep_range(200, 500);
147+
break;
148+
}
130149

131150
/* Polling to check the phy is ready or not. */
132151
ret = readl_poll_timeout(imx8_phy->base + IMX8MM_PCIE_PHY_CMN_REG075,
@@ -157,6 +176,17 @@ static const struct phy_ops imx8_pcie_phy_ops = {
157176
.owner = THIS_MODULE,
158177
};
159178

179+
static const struct imx8_pcie_phy_drvdata imx8mm_drvdata = {
180+
.gpr = "fsl,imx8mm-iomuxc-gpr",
181+
.variant = IMX8MM,
182+
};
183+
184+
static const struct of_device_id imx8_pcie_phy_of_match[] = {
185+
{.compatible = "fsl,imx8mm-pcie-phy", .data = &imx8mm_drvdata, },
186+
{ },
187+
};
188+
MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
189+
160190
static int imx8_pcie_phy_probe(struct platform_device *pdev)
161191
{
162192
struct phy_provider *phy_provider;
@@ -169,6 +199,8 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev)
169199
if (!imx8_phy)
170200
return -ENOMEM;
171201

202+
imx8_phy->drvdata = of_device_get_match_data(dev);
203+
172204
/* get PHY refclk pad mode */
173205
of_property_read_u32(np, "fsl,refclk-pad-mode",
174206
&imx8_phy->refclk_pad_mode);
@@ -194,7 +226,7 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev)
194226

195227
/* Grab GPR config register range */
196228
imx8_phy->iomuxc_gpr =
197-
syscon_regmap_lookup_by_compatible("fsl,imx6q-iomuxc-gpr");
229+
syscon_regmap_lookup_by_compatible(imx8_phy->drvdata->gpr);
198230
if (IS_ERR(imx8_phy->iomuxc_gpr)) {
199231
dev_err(dev, "unable to find iomuxc registers\n");
200232
return PTR_ERR(imx8_phy->iomuxc_gpr);
@@ -222,12 +254,6 @@ static int imx8_pcie_phy_probe(struct platform_device *pdev)
222254
return PTR_ERR_OR_ZERO(phy_provider);
223255
}
224256

225-
static const struct of_device_id imx8_pcie_phy_of_match[] = {
226-
{.compatible = "fsl,imx8mm-pcie-phy",},
227-
{ },
228-
};
229-
MODULE_DEVICE_TABLE(of, imx8_pcie_phy_of_match);
230-
231257
static struct platform_driver imx8_pcie_phy_driver = {
232258
.probe = imx8_pcie_phy_probe,
233259
.driver = {

0 commit comments

Comments
 (0)