diff mbox

[v2,10/11] phy: rockchip-emmc: Set phyctrl_frqsel based on card clock

Message ID 1465859076-4868-11-git-send-email-dianders@chromium.org (mailing list archive)
State New, archived
Headers show

Commit Message

Doug Anderson June 13, 2016, 11:04 p.m. UTC
The "phyctrl_frqsel" is described in the Arasan datasheet [1] as "the
frequency range of DLL operation".  Although the Rockchip variant of
this PHY has different ranges than the reference Arasan PHY it appears
as if the functionality is similar.  We should set this phyctrl field
properly.

Note: as per Rockchip engineers, apparently the "phyctrl_frqsel" is
actually only useful in HS200 / HS400 modes even though the DLL itself
it used for some purposes in all modes.  See the discussion in the
earlier change in this series: ("mmc: sdhci-of-arasan: Always power the
PHY off/on when clock changes").  In any case, it shouldn't hurt to set
this always.

Note that this change should allow boards to run at HS200 / HS400 speed
modes while running at 100 MHz or 150 MHz.  In fact, running HS400 at
150 MHz (giving 300 MB/s) is the main motivation of this series, since
performance is still good but signal integrity problems are less
prevelant at 150 MHz.

[1]: https://arasan.com/wp-content/media/eMMC-5-1-Total-Solution_Rev-1-3.pdf

Signed-off-by: Douglas Anderson <dianders@chromium.org>
---
Changes in v2:
- Warn if we're more than 15 MHz from ideal rate (Shawn)
- Move code cleanup before set phyctrl_frqsel based on card clock (Shawn)
- Fix typo USB => SDHCI (Shawn)

 drivers/phy/phy-rockchip-emmc.c | 82 ++++++++++++++++++++++++++++++++++-------
 1 file changed, 69 insertions(+), 13 deletions(-)

Comments

Heiko Stübner June 18, 2016, 12:20 p.m. UTC | #1
Am Montag, 13. Juni 2016, 16:04:34 schrieb Douglas Anderson:
> The "phyctrl_frqsel" is described in the Arasan datasheet [1] as "the
> frequency range of DLL operation".  Although the Rockchip variant of
> this PHY has different ranges than the reference Arasan PHY it appears
> as if the functionality is similar.  We should set this phyctrl field
> properly.
> 
> Note: as per Rockchip engineers, apparently the "phyctrl_frqsel" is
> actually only useful in HS200 / HS400 modes even though the DLL itself
> it used for some purposes in all modes.  See the discussion in the
> earlier change in this series: ("mmc: sdhci-of-arasan: Always power the
> PHY off/on when clock changes").  In any case, it shouldn't hurt to set
> this always.
> 
> Note that this change should allow boards to run at HS200 / HS400 speed
> modes while running at 100 MHz or 150 MHz.  In fact, running HS400 at
> 150 MHz (giving 300 MB/s) is the main motivation of this series, since
> performance is still good but signal integrity problems are less
> prevelant at 150 MHz.
> 
> [1]: https://arasan.com/wp-content/media/eMMC-5-1-Total-Solution_Rev-1-3.pdf
> 
> Signed-off-by: Douglas Anderson <dianders@chromium.org>
> ---
> Changes in v2:
> - Warn if we're more than 15 MHz from ideal rate (Shawn)
> - Move code cleanup before set phyctrl_frqsel based on card clock (Shawn)
> - Fix typo USB => SDHCI (Shawn)
> 
>  drivers/phy/phy-rockchip-emmc.c | 82
> ++++++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+),
> 13 deletions(-)
> 
> diff --git a/drivers/phy/phy-rockchip-emmc.c
> b/drivers/phy/phy-rockchip-emmc.c index 23fe50864526..51ddd543fd04 100644
> --- a/drivers/phy/phy-rockchip-emmc.c
> +++ b/drivers/phy/phy-rockchip-emmc.c
> @@ -14,6 +14,7 @@
>   * GNU General Public License for more details.
>   */
> 
> +#include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/mfd/syscon.h>
>  #include <linux/module.h>
> @@ -78,16 +79,73 @@
>  struct rockchip_emmc_phy {
>  	unsigned int	reg_offset;
>  	struct regmap	*reg_base;
> +	struct clk	*emmcclk;
>  };
> 
> -static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
> -				   bool on_off)
> +static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
>  {
> +	struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
>  	unsigned int caldone;
>  	unsigned int dllrdy;
> +	unsigned int freqsel = PHYCTRL_FREQSEL_200M;
>  	unsigned long timeout;
> 
>  	/*
> +	 * We purposely get the clock here and not in probe to avoid the
> +	 * circular dependency problem.  We expect:
> +	 * - PHY driver to probe
> +	 * - SDHCI driver to start probe
> +	 * - SDHCI driver to register it's clock
> +	 * - SDHCI driver to get the PHY
> +	 * - SDHCI driver to power on the PHY
> +	 */

Doesn't that leave open the unbind / removal case with that same circular 
dependency? While true that the clock-framework does some special handling on 
clk_unregister, I don't think this would catch multiple unbind/bind actions.

The emmc-phy would still hold on to the old clock-instance with the empty clk-
ops the ccf assigns, even when the rebind of the arasan-sdhci would create a 
new clock.

How about using phy-init / phy-exit callbacks for that instead? (Aka clk_get 
and clk_put the emmc clock in there instead of using the devm variant)


> +	if (!rk_phy->emmcclk) {
> +		rk_phy->emmcclk = devm_clk_get(&phy->dev, "emmcclk");
> +
> +		/* Don't expect defer at this point; try next time */
> +		if (PTR_ERR(rk_phy->emmcclk) == -EPROBE_DEFER) {
> +			dev_warn(&phy->dev, "Unexpected emmcclk defer\n");
> +			rk_phy->emmcclk = NULL;
> +		}
> +	}
> +
> +	if (!IS_ERR_OR_NULL(rk_phy->emmcclk)) {

you just made it NULL in the error case above?


Heiko
Kishon Vijay Abraham I June 20, 2016, 1:08 p.m. UTC | #2
On Tuesday 14 June 2016 04:34 AM, Douglas Anderson wrote:
> The "phyctrl_frqsel" is described in the Arasan datasheet [1] as "the
> frequency range of DLL operation".  Although the Rockchip variant of
> this PHY has different ranges than the reference Arasan PHY it appears
> as if the functionality is similar.  We should set this phyctrl field
> properly.
> 
> Note: as per Rockchip engineers, apparently the "phyctrl_frqsel" is
> actually only useful in HS200 / HS400 modes even though the DLL itself
> it used for some purposes in all modes.  See the discussion in the
> earlier change in this series: ("mmc: sdhci-of-arasan: Always power the
> PHY off/on when clock changes").  In any case, it shouldn't hurt to set
> this always.
> 
> Note that this change should allow boards to run at HS200 / HS400 speed
> modes while running at 100 MHz or 150 MHz.  In fact, running HS400 at
> 150 MHz (giving 300 MB/s) is the main motivation of this series, since
> performance is still good but signal integrity problems are less
> prevelant at 150 MHz.
> 
> [1]: https://arasan.com/wp-content/media/eMMC-5-1-Total-Solution_Rev-1-3.pdf
> 
> Signed-off-by: Douglas Anderson <dianders@chromium.org>

Acked-by: Kishon Vijay Abraham I <kishon@ti.com>
> ---
> Changes in v2:
> - Warn if we're more than 15 MHz from ideal rate (Shawn)
> - Move code cleanup before set phyctrl_frqsel based on card clock (Shawn)
> - Fix typo USB => SDHCI (Shawn)
> 
>  drivers/phy/phy-rockchip-emmc.c | 82 ++++++++++++++++++++++++++++++++++-------
>  1 file changed, 69 insertions(+), 13 deletions(-)
> 
> diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c
> index 23fe50864526..51ddd543fd04 100644
> --- a/drivers/phy/phy-rockchip-emmc.c
> +++ b/drivers/phy/phy-rockchip-emmc.c
> @@ -14,6 +14,7 @@
>   * GNU General Public License for more details.
>   */
>  
> +#include <linux/clk.h>
>  #include <linux/delay.h>
>  #include <linux/mfd/syscon.h>
>  #include <linux/module.h>
> @@ -78,16 +79,73 @@
>  struct rockchip_emmc_phy {
>  	unsigned int	reg_offset;
>  	struct regmap	*reg_base;
> +	struct clk	*emmcclk;
>  };
>  
> -static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
> -				   bool on_off)
> +static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
>  {
> +	struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
>  	unsigned int caldone;
>  	unsigned int dllrdy;
> +	unsigned int freqsel = PHYCTRL_FREQSEL_200M;
>  	unsigned long timeout;
>  
>  	/*
> +	 * We purposely get the clock here and not in probe to avoid the
> +	 * circular dependency problem.  We expect:
> +	 * - PHY driver to probe
> +	 * - SDHCI driver to start probe
> +	 * - SDHCI driver to register it's clock
> +	 * - SDHCI driver to get the PHY
> +	 * - SDHCI driver to power on the PHY
> +	 */
> +	if (!rk_phy->emmcclk) {
> +		rk_phy->emmcclk = devm_clk_get(&phy->dev, "emmcclk");
> +
> +		/* Don't expect defer at this point; try next time */
> +		if (PTR_ERR(rk_phy->emmcclk) == -EPROBE_DEFER) {
> +			dev_warn(&phy->dev, "Unexpected emmcclk defer\n");
> +			rk_phy->emmcclk = NULL;
> +		}
> +	}
> +
> +	if (!IS_ERR_OR_NULL(rk_phy->emmcclk)) {
> +		unsigned long rate = clk_get_rate(rk_phy->emmcclk);
> +		unsigned long ideal_rate;
> +		unsigned long diff;
> +
> +		switch (rate) {
> +		case 0 ... 74999999:
> +			ideal_rate = 50000000;
> +			freqsel = PHYCTRL_FREQSEL_50M;
> +			break;
> +		case 75000000 ... 124999999:
> +			ideal_rate = 100000000;
> +			freqsel = PHYCTRL_FREQSEL_100M;
> +			break;
> +		case 125000000 ... 174999999:
> +			ideal_rate = 150000000;
> +			freqsel = PHYCTRL_FREQSEL_150M;
> +			break;
> +		default:
> +			ideal_rate = 200000000;
> +			break;
> +		};
> +
> +		diff = (rate > ideal_rate) ?
> +			rate - ideal_rate : ideal_rate - rate;
> +
> +		/*
> +		 * In order for tuning delays to be accurate we need to be
> +		 * pretty spot on for the DLL range, so warn if we're too
> +		 * far off.  Also warn if we're above the 200 MHz max.  Don't
> +		 * warn for really slow rates since we won't be tuning then.
> +		 */
> +		if ((rate > 50000000 && diff > 15000000) || (rate > 200000000))
> +			dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
> +	}
> +
> +	/*
>  	 * Keep phyctrl_pdb and phyctrl_endll low to allow
>  	 * initialization of CALIO state M/C DFFs
>  	 */
> @@ -132,6 +190,13 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
>  		return -ETIMEDOUT;
>  	}
>  
> +	/* Set the frequency of the DLL operation */
> +	regmap_write(rk_phy->reg_base,
> +		     rk_phy->reg_offset + GRF_EMMCPHY_CON0,
> +		     HIWORD_UPDATE(freqsel, PHYCTRL_FREQSEL_MASK,
> +				   PHYCTRL_FREQSEL_SHIFT));
> +
> +	/* Turn on the DLL */
>  	regmap_write(rk_phy->reg_base,
>  		     rk_phy->reg_offset + GRF_EMMCPHY_CON6,
>  		     HIWORD_UPDATE(PHYCTRL_ENDLL_ENABLE,
> @@ -168,23 +233,14 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
>  
>  static int rockchip_emmc_phy_power_off(struct phy *phy)
>  {
> -	struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
> -
>  	/* Power down emmc phy analog blocks */
> -	return rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_OFF);
> +	return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_OFF);
>  }
>  
>  static int rockchip_emmc_phy_power_on(struct phy *phy)
>  {
>  	struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
>  
> -	/* DLL operation: 200 MHz */
> -	regmap_write(rk_phy->reg_base,
> -		     rk_phy->reg_offset + GRF_EMMCPHY_CON0,
> -		     HIWORD_UPDATE(PHYCTRL_FREQSEL_200M,
> -				   PHYCTRL_FREQSEL_MASK,
> -				   PHYCTRL_FREQSEL_SHIFT));
> -
>  	/* Drive impedance: 50 Ohm */
>  	regmap_write(rk_phy->reg_base,
>  		     rk_phy->reg_offset + GRF_EMMCPHY_CON6,
> @@ -207,7 +263,7 @@ static int rockchip_emmc_phy_power_on(struct phy *phy)
>  				   PHYCTRL_OTAPDLYSEL_SHIFT));
>  
>  	/* Power up emmc phy analog blocks */
> -	return rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_ON);
> +	return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_ON);
>  }
>  
>  static const struct phy_ops ops = {
>
Doug Anderson June 20, 2016, 4:48 p.m. UTC | #3
Heiko,

On Sat, Jun 18, 2016 at 5:20 AM, Heiko Stübner <heiko@sntech.de> wrote:
> Am Montag, 13. Juni 2016, 16:04:34 schrieb Douglas Anderson:
>> The "phyctrl_frqsel" is described in the Arasan datasheet [1] as "the
>> frequency range of DLL operation".  Although the Rockchip variant of
>> this PHY has different ranges than the reference Arasan PHY it appears
>> as if the functionality is similar.  We should set this phyctrl field
>> properly.
>>
>> Note: as per Rockchip engineers, apparently the "phyctrl_frqsel" is
>> actually only useful in HS200 / HS400 modes even though the DLL itself
>> it used for some purposes in all modes.  See the discussion in the
>> earlier change in this series: ("mmc: sdhci-of-arasan: Always power the
>> PHY off/on when clock changes").  In any case, it shouldn't hurt to set
>> this always.
>>
>> Note that this change should allow boards to run at HS200 / HS400 speed
>> modes while running at 100 MHz or 150 MHz.  In fact, running HS400 at
>> 150 MHz (giving 300 MB/s) is the main motivation of this series, since
>> performance is still good but signal integrity problems are less
>> prevelant at 150 MHz.
>>
>> [1]: https://arasan.com/wp-content/media/eMMC-5-1-Total-Solution_Rev-1-3.pdf
>>
>> Signed-off-by: Douglas Anderson <dianders@chromium.org>
>> ---
>> Changes in v2:
>> - Warn if we're more than 15 MHz from ideal rate (Shawn)
>> - Move code cleanup before set phyctrl_frqsel based on card clock (Shawn)
>> - Fix typo USB => SDHCI (Shawn)
>>
>>  drivers/phy/phy-rockchip-emmc.c | 82
>> ++++++++++++++++++++++++++++++++++------- 1 file changed, 69 insertions(+),
>> 13 deletions(-)
>>
>> diff --git a/drivers/phy/phy-rockchip-emmc.c
>> b/drivers/phy/phy-rockchip-emmc.c index 23fe50864526..51ddd543fd04 100644
>> --- a/drivers/phy/phy-rockchip-emmc.c
>> +++ b/drivers/phy/phy-rockchip-emmc.c
>> @@ -14,6 +14,7 @@
>>   * GNU General Public License for more details.
>>   */
>>
>> +#include <linux/clk.h>
>>  #include <linux/delay.h>
>>  #include <linux/mfd/syscon.h>
>>  #include <linux/module.h>
>> @@ -78,16 +79,73 @@
>>  struct rockchip_emmc_phy {
>>       unsigned int    reg_offset;
>>       struct regmap   *reg_base;
>> +     struct clk      *emmcclk;
>>  };
>>
>> -static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
>> -                                bool on_off)
>> +static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
>>  {
>> +     struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
>>       unsigned int caldone;
>>       unsigned int dllrdy;
>> +     unsigned int freqsel = PHYCTRL_FREQSEL_200M;
>>       unsigned long timeout;
>>
>>       /*
>> +      * We purposely get the clock here and not in probe to avoid the
>> +      * circular dependency problem.  We expect:
>> +      * - PHY driver to probe
>> +      * - SDHCI driver to start probe
>> +      * - SDHCI driver to register it's clock
>> +      * - SDHCI driver to get the PHY
>> +      * - SDHCI driver to power on the PHY
>> +      */
>
> Doesn't that leave open the unbind / removal case with that same circular
> dependency? While true that the clock-framework does some special handling on
> clk_unregister, I don't think this would catch multiple unbind/bind actions.
>
> The emmc-phy would still hold on to the old clock-instance with the empty clk-
> ops the ccf assigns, even when the rebind of the arasan-sdhci would create a
> new clock.
>
> How about using phy-init / phy-exit callbacks for that instead? (Aka clk_get
> and clk_put the emmc clock in there instead of using the devm variant)

Using phy-init and phy-exit is perfect.  I'll spin shortly.

>> +     if (!rk_phy->emmcclk) {
>> +             rk_phy->emmcclk = devm_clk_get(&phy->dev, "emmcclk");
>> +
>> +             /* Don't expect defer at this point; try next time */
>> +             if (PTR_ERR(rk_phy->emmcclk) == -EPROBE_DEFER) {
>> +                     dev_warn(&phy->dev, "Unexpected emmcclk defer\n");
>> +                     rk_phy->emmcclk = NULL;
>> +             }
>> +     }
>> +
>> +     if (!IS_ERR_OR_NULL(rk_phy->emmcclk)) {
>
> you just made it NULL in the error case above?

Yeah.  The idea was the if we happened to get a EPROBE_DEFER (should
never happen) we would continue on and just skip this part.  In any
case, should be a moot point with the new version, which I'll send out
soon.

-Doug
diff mbox

Patch

diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c
index 23fe50864526..51ddd543fd04 100644
--- a/drivers/phy/phy-rockchip-emmc.c
+++ b/drivers/phy/phy-rockchip-emmc.c
@@ -14,6 +14,7 @@ 
  * GNU General Public License for more details.
  */
 
+#include <linux/clk.h>
 #include <linux/delay.h>
 #include <linux/mfd/syscon.h>
 #include <linux/module.h>
@@ -78,16 +79,73 @@ 
 struct rockchip_emmc_phy {
 	unsigned int	reg_offset;
 	struct regmap	*reg_base;
+	struct clk	*emmcclk;
 };
 
-static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
-				   bool on_off)
+static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
 {
+	struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
 	unsigned int caldone;
 	unsigned int dllrdy;
+	unsigned int freqsel = PHYCTRL_FREQSEL_200M;
 	unsigned long timeout;
 
 	/*
+	 * We purposely get the clock here and not in probe to avoid the
+	 * circular dependency problem.  We expect:
+	 * - PHY driver to probe
+	 * - SDHCI driver to start probe
+	 * - SDHCI driver to register it's clock
+	 * - SDHCI driver to get the PHY
+	 * - SDHCI driver to power on the PHY
+	 */
+	if (!rk_phy->emmcclk) {
+		rk_phy->emmcclk = devm_clk_get(&phy->dev, "emmcclk");
+
+		/* Don't expect defer at this point; try next time */
+		if (PTR_ERR(rk_phy->emmcclk) == -EPROBE_DEFER) {
+			dev_warn(&phy->dev, "Unexpected emmcclk defer\n");
+			rk_phy->emmcclk = NULL;
+		}
+	}
+
+	if (!IS_ERR_OR_NULL(rk_phy->emmcclk)) {
+		unsigned long rate = clk_get_rate(rk_phy->emmcclk);
+		unsigned long ideal_rate;
+		unsigned long diff;
+
+		switch (rate) {
+		case 0 ... 74999999:
+			ideal_rate = 50000000;
+			freqsel = PHYCTRL_FREQSEL_50M;
+			break;
+		case 75000000 ... 124999999:
+			ideal_rate = 100000000;
+			freqsel = PHYCTRL_FREQSEL_100M;
+			break;
+		case 125000000 ... 174999999:
+			ideal_rate = 150000000;
+			freqsel = PHYCTRL_FREQSEL_150M;
+			break;
+		default:
+			ideal_rate = 200000000;
+			break;
+		};
+
+		diff = (rate > ideal_rate) ?
+			rate - ideal_rate : ideal_rate - rate;
+
+		/*
+		 * In order for tuning delays to be accurate we need to be
+		 * pretty spot on for the DLL range, so warn if we're too
+		 * far off.  Also warn if we're above the 200 MHz max.  Don't
+		 * warn for really slow rates since we won't be tuning then.
+		 */
+		if ((rate > 50000000 && diff > 15000000) || (rate > 200000000))
+			dev_warn(&phy->dev, "Unsupported rate: %lu\n", rate);
+	}
+
+	/*
 	 * Keep phyctrl_pdb and phyctrl_endll low to allow
 	 * initialization of CALIO state M/C DFFs
 	 */
@@ -132,6 +190,13 @@  static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
 		return -ETIMEDOUT;
 	}
 
+	/* Set the frequency of the DLL operation */
+	regmap_write(rk_phy->reg_base,
+		     rk_phy->reg_offset + GRF_EMMCPHY_CON0,
+		     HIWORD_UPDATE(freqsel, PHYCTRL_FREQSEL_MASK,
+				   PHYCTRL_FREQSEL_SHIFT));
+
+	/* Turn on the DLL */
 	regmap_write(rk_phy->reg_base,
 		     rk_phy->reg_offset + GRF_EMMCPHY_CON6,
 		     HIWORD_UPDATE(PHYCTRL_ENDLL_ENABLE,
@@ -168,23 +233,14 @@  static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
 
 static int rockchip_emmc_phy_power_off(struct phy *phy)
 {
-	struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
-
 	/* Power down emmc phy analog blocks */
-	return rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_OFF);
+	return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_OFF);
 }
 
 static int rockchip_emmc_phy_power_on(struct phy *phy)
 {
 	struct rockchip_emmc_phy *rk_phy = phy_get_drvdata(phy);
 
-	/* DLL operation: 200 MHz */
-	regmap_write(rk_phy->reg_base,
-		     rk_phy->reg_offset + GRF_EMMCPHY_CON0,
-		     HIWORD_UPDATE(PHYCTRL_FREQSEL_200M,
-				   PHYCTRL_FREQSEL_MASK,
-				   PHYCTRL_FREQSEL_SHIFT));
-
 	/* Drive impedance: 50 Ohm */
 	regmap_write(rk_phy->reg_base,
 		     rk_phy->reg_offset + GRF_EMMCPHY_CON6,
@@ -207,7 +263,7 @@  static int rockchip_emmc_phy_power_on(struct phy *phy)
 				   PHYCTRL_OTAPDLYSEL_SHIFT));
 
 	/* Power up emmc phy analog blocks */
-	return rockchip_emmc_phy_power(rk_phy, PHYCTRL_PDB_PWR_ON);
+	return rockchip_emmc_phy_power(phy, PHYCTRL_PDB_PWR_ON);
 }
 
 static const struct phy_ops ops = {