aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy
diff options
context:
space:
mode:
authorDouglas Anderson <dianders@chromium.org>2016-06-20 13:56:44 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2016-07-25 04:34:16 -0400
commit49f9ccd8882c1b97512ece16ad68ad0594c54bbc (patch)
tree1bfa1ca68520db062fb814db82e2240cba077978 /drivers/phy
parent675f65c444e85ab889d299d2a7ce62d5d478e478 (diff)
phy: rockchip-emmc: Increase lock time allowance
Previous PHY code waited a fixed amount of time for the DLL to lock at power on time. Unfortunately, the time for the DLL to lock is actually a bit more dynamic and can be longer if the card clock is slower. Instead of waiting a fixed 30 us, let's now dynamically wait until the lock bit gets set. We'll wait up to 10 ms which should be OK even if the card clock is at the super slow 100 kHz. On its own, this change makes the PHY power on code a little more robust. Before this change the PHY was relying on the eMMC code to make sure the PHY was only powered on when the card clock was set to at least 50 MHz before, though this reliance wasn't documented anywhere. This change will be even more useful in future changes where we actually need to be able to wait for a DLL lock at slower clock speeds. Signed-off-by: Douglas Anderson <dianders@chromium.org> Acked-by: Kishon Vijay Abraham I <kishon@ti.com> Reviewed-by: Shawn Lin <shawn.lin@rock-chips.com> Tested-by: Heiko Stuebner <heiko@sntech.de> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/phy-rockchip-emmc.c28
1 files changed, 20 insertions, 8 deletions
diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c
index a69f53630e67..2d059c046978 100644
--- a/drivers/phy/phy-rockchip-emmc.c
+++ b/drivers/phy/phy-rockchip-emmc.c
@@ -85,6 +85,7 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
85{ 85{
86 unsigned int caldone; 86 unsigned int caldone;
87 unsigned int dllrdy; 87 unsigned int dllrdy;
88 unsigned long timeout;
88 89
89 /* 90 /*
90 * Keep phyctrl_pdb and phyctrl_endll low to allow 91 * Keep phyctrl_pdb and phyctrl_endll low to allow
@@ -137,15 +138,26 @@ static int rockchip_emmc_phy_power(struct rockchip_emmc_phy *rk_phy,
137 PHYCTRL_ENDLL_MASK, 138 PHYCTRL_ENDLL_MASK,
138 PHYCTRL_ENDLL_SHIFT)); 139 PHYCTRL_ENDLL_SHIFT));
139 /* 140 /*
140 * After enable analog DLL circuits, we need an extra 10.2us 141 * After enabling analog DLL circuits docs say that we need 10.2 us if
141 * for dll to be ready for work. But according to testing, we 142 * our source clock is at 50 MHz and that lock time scales linearly
142 * find some chips need more than 25us. 143 * with clock speed. If we are powering on the PHY and the card clock
144 * is super slow (like 100 kHZ) this could take as long as 5.1 ms as
145 * per the math: 10.2 us * (50000000 Hz / 100000 Hz) => 5.1 ms
146 * Hopefully we won't be running at 100 kHz, but we should still make
147 * sure we wait long enough.
143 */ 148 */
144 udelay(30); 149 timeout = jiffies + msecs_to_jiffies(10);
145 regmap_read(rk_phy->reg_base, 150 do {
146 rk_phy->reg_offset + GRF_EMMCPHY_STATUS, 151 udelay(1);
147 &dllrdy); 152
148 dllrdy = (dllrdy >> PHYCTRL_DLLRDY_SHIFT) & PHYCTRL_DLLRDY_MASK; 153 regmap_read(rk_phy->reg_base,
154 rk_phy->reg_offset + GRF_EMMCPHY_STATUS,
155 &dllrdy);
156 dllrdy = (dllrdy >> PHYCTRL_DLLRDY_SHIFT) & PHYCTRL_DLLRDY_MASK;
157 if (dllrdy == PHYCTRL_DLLRDY_DONE)
158 break;
159 } while (!time_after(jiffies, timeout));
160
149 if (dllrdy != PHYCTRL_DLLRDY_DONE) { 161 if (dllrdy != PHYCTRL_DLLRDY_DONE) {
150 pr_err("rockchip_emmc_phy_power: dllrdy timeout.\n"); 162 pr_err("rockchip_emmc_phy_power: dllrdy timeout.\n");
151 return -ETIMEDOUT; 163 return -ETIMEDOUT;