Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

phy: samsung-ufs: ufs: change phy on/off control

The sequence of controlling ufs phy block should be below:

1) Power On
- Turn off pmu isolation
- Clock enable
2) Power Off
- Clock disable
- Turn on pmu isolation

Signed-off-by: Chanho Park <chanho61.park@samsung.com>
Reviewed-by: Krzysztof Kozlowski <krzysztof.kozlowski@linaro.org>
Link: https://lore.kernel.org/r/20220706020255.151177-3-chanho61.park@samsung.com
Signed-off-by: Vinod Koul <vkoul@kernel.org>

authored by

Chanho Park and committed by
Vinod Koul
4e123efa 8d5bb683

+19 -13
+19 -13
drivers/phy/samsung/phy-samsung-ufs.c
··· 151 151 static int samsung_ufs_phy_init(struct phy *phy) 152 152 { 153 153 struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy); 154 - int ret; 155 154 156 155 ss_phy->lane_cnt = phy->attrs.bus_width; 157 156 ss_phy->ufs_phy_state = CFG_PRE_INIT; 157 + 158 + return 0; 159 + } 160 + 161 + static int samsung_ufs_phy_power_on(struct phy *phy) 162 + { 163 + struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy); 164 + int ret; 165 + 166 + samsung_ufs_phy_ctrl_isol(ss_phy, false); 158 167 159 168 ret = clk_bulk_prepare_enable(ss_phy->drvdata->num_clks, ss_phy->clks); 160 169 if (ret) { ··· 171 162 return ret; 172 163 } 173 164 174 - ret = samsung_ufs_phy_calibrate(phy); 175 - if (ret) 176 - dev_err(ss_phy->dev, "ufs phy calibration failed\n"); 165 + if (ss_phy->ufs_phy_state == CFG_PRE_INIT) { 166 + ret = samsung_ufs_phy_calibrate(phy); 167 + if (ret) 168 + dev_err(ss_phy->dev, "ufs phy calibration failed\n"); 169 + } 177 170 178 171 return ret; 179 - } 180 - 181 - static int samsung_ufs_phy_power_on(struct phy *phy) 182 - { 183 - struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy); 184 - 185 - samsung_ufs_phy_ctrl_isol(ss_phy, false); 186 - return 0; 187 172 } 188 173 189 174 static int samsung_ufs_phy_power_off(struct phy *phy) 190 175 { 191 176 struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy); 192 177 178 + clk_bulk_disable_unprepare(ss_phy->drvdata->num_clks, ss_phy->clks); 179 + 193 180 samsung_ufs_phy_ctrl_isol(ss_phy, true); 181 + 194 182 return 0; 195 183 } 196 184 ··· 208 202 { 209 203 struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy); 210 204 211 - clk_bulk_disable_unprepare(ss_phy->drvdata->num_clks, ss_phy->clks); 205 + ss_phy->ufs_phy_state = CFG_TAG_MAX; 212 206 213 207 return 0; 214 208 }