aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/phy
diff options
context:
space:
mode:
authorDouglas Anderson <dianders@chromium.org>2016-06-27 13:39:26 -0400
committerUlf Hansson <ulf.hansson@linaro.org>2016-07-25 04:38:00 -0400
commit4e2ea670861f2068082da310f25815c7498a41dc (patch)
tree43835a03c84a798e585839b68ba67a61d18f22f2 /drivers/phy
parent6fc09244d74ded1c7210fb493a17e7c29dde2010 (diff)
phy: rockchip-emmc: Be tolerant to card clock of 0 in power on
It's possible that there are some reasons to turn the PHY on while the clock is 0. In this case we just won't wait for the DLL to lock. This is a bit of a stopgap until we figure out exactly when we're supposed to wait for the DLL to lock and when we're supposed to power cycle the PHY. Note: this patch should help with suspend/resume where the system will try to turn the PHY back on when the clock is 0. Signed-off-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Kishon Vijay Abraham I <kishon@ti.com> Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
Diffstat (limited to 'drivers/phy')
-rw-r--r--drivers/phy/phy-rockchip-emmc.c59
1 files changed, 37 insertions, 22 deletions
diff --git a/drivers/phy/phy-rockchip-emmc.c b/drivers/phy/phy-rockchip-emmc.c
index 9dce958233a0..a2aa6aca7dec 100644
--- a/drivers/phy/phy-rockchip-emmc.c
+++ b/drivers/phy/phy-rockchip-emmc.c
@@ -88,15 +88,36 @@ static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
88 unsigned int caldone; 88 unsigned int caldone;
89 unsigned int dllrdy; 89 unsigned int dllrdy;
90 unsigned int freqsel = PHYCTRL_FREQSEL_200M; 90 unsigned int freqsel = PHYCTRL_FREQSEL_200M;
91 unsigned long rate;
91 unsigned long timeout; 92 unsigned long timeout;
92 93
93 if (rk_phy->emmcclk != NULL) { 94 /*
94 unsigned long rate = clk_get_rate(rk_phy->emmcclk); 95 * Keep phyctrl_pdb and phyctrl_endll low to allow
96 * initialization of CALIO state M/C DFFs
97 */
98 regmap_write(rk_phy->reg_base,
99 rk_phy->reg_offset + GRF_EMMCPHY_CON6,
100 HIWORD_UPDATE(PHYCTRL_PDB_PWR_OFF,
101 PHYCTRL_PDB_MASK,
102 PHYCTRL_PDB_SHIFT));
103 regmap_write(rk_phy->reg_base,
104 rk_phy->reg_offset + GRF_EMMCPHY_CON6,
105 HIWORD_UPDATE(PHYCTRL_ENDLL_DISABLE,
106 PHYCTRL_ENDLL_MASK,
107 PHYCTRL_ENDLL_SHIFT));
108
109 /* Already finish power_off above */
110 if (on_off == PHYCTRL_PDB_PWR_OFF)
111 return 0;
112
113 rate = clk_get_rate(rk_phy->emmcclk);
114
115 if (rate != 0) {
95 unsigned long ideal_rate; 116 unsigned long ideal_rate;
96 unsigned long diff; 117 unsigned long diff;
97 118
98 switch (rate) { 119 switch (rate) {
99 case 0 ... 74999999: 120 case 1 ... 74999999:
100 ideal_rate = 50000000; 121 ideal_rate = 50000000;
101 freqsel = PHYCTRL_FREQSEL_50M; 122 freqsel = PHYCTRL_FREQSEL_50M;
102 break; 123 break;
@@ -127,25 +148,6 @@ static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
127 } 148 }
128 149
129 /* 150 /*
130 * Keep phyctrl_pdb and phyctrl_endll low to allow
131 * initialization of CALIO state M/C DFFs
132 */
133 regmap_write(rk_phy->reg_base,
134 rk_phy->reg_offset + GRF_EMMCPHY_CON6,
135 HIWORD_UPDATE(PHYCTRL_PDB_PWR_OFF,
136 PHYCTRL_PDB_MASK,
137 PHYCTRL_PDB_SHIFT));
138 regmap_write(rk_phy->reg_base,
139 rk_phy->reg_offset + GRF_EMMCPHY_CON6,
140 HIWORD_UPDATE(PHYCTRL_ENDLL_DISABLE,
141 PHYCTRL_ENDLL_MASK,
142 PHYCTRL_ENDLL_SHIFT));
143
144 /* Already finish power_off above */
145 if (on_off == PHYCTRL_PDB_PWR_OFF)
146 return 0;
147
148 /*
149 * According to the user manual, calpad calibration 151 * According to the user manual, calpad calibration
150 * cycle takes more than 2us without the minimal recommended 152 * cycle takes more than 2us without the minimal recommended
151 * value, so we may need a little margin here 153 * value, so we may need a little margin here
@@ -183,6 +185,19 @@ static int rockchip_emmc_phy_power(struct phy *phy, bool on_off)
183 HIWORD_UPDATE(PHYCTRL_ENDLL_ENABLE, 185 HIWORD_UPDATE(PHYCTRL_ENDLL_ENABLE,
184 PHYCTRL_ENDLL_MASK, 186 PHYCTRL_ENDLL_MASK,
185 PHYCTRL_ENDLL_SHIFT)); 187 PHYCTRL_ENDLL_SHIFT));
188
189 /*
190 * We turned on the DLL even though the rate was 0 because we the
191 * clock might be turned on later. ...but we can't wait for the DLL
192 * to lock when the rate is 0 because it will never lock with no
193 * input clock.
194 *
195 * Technically we should be checking the lock later when the clock
196 * is turned on, but for now we won't.
197 */
198 if (rate == 0)
199 return 0;
200
186 /* 201 /*
187 * After enabling analog DLL circuits docs say that we need 10.2 us if 202 * After enabling analog DLL circuits docs say that we need 10.2 us if
188 * our source clock is at 50 MHz and that lock time scales linearly 203 * our source clock is at 50 MHz and that lock time scales linearly