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>
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+
4858struct 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
6071static 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+
160190static 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-
231257static struct platform_driver imx8_pcie_phy_driver = {
232258 .probe = imx8_pcie_phy_probe ,
233259 .driver = {
0 commit comments