summaryrefslogtreecommitdiff
path: root/drivers/phy/samsung/phy-samsung-ufs.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/phy/samsung/phy-samsung-ufs.c')
-rw-r--r--drivers/phy/samsung/phy-samsung-ufs.c40
1 files changed, 40 insertions, 0 deletions
diff --git a/drivers/phy/samsung/phy-samsung-ufs.c b/drivers/phy/samsung/phy-samsung-ufs.c
index f3cbe6b17b23..ee665f26c236 100644
--- a/drivers/phy/samsung/phy-samsung-ufs.c
+++ b/drivers/phy/samsung/phy-samsung-ufs.c
@@ -217,6 +217,44 @@ static int samsung_ufs_phy_set_mode(struct phy *generic_phy,
return 0;
}
+static int samsung_ufs_phy_notify_state(struct phy *phy,
+ union phy_notify state)
+{
+ struct samsung_ufs_phy *ufs_phy = get_samsung_ufs_phy(phy);
+ const struct samsung_ufs_phy_cfg *cfg;
+ int i, err = -EINVAL;
+
+ if (!ufs_phy->cfgs_hibern8)
+ return 0;
+
+ if (state.ufs_state == PHY_UFS_HIBERN8_ENTER)
+ cfg = ufs_phy->cfgs_hibern8[CFG_POST_HIBERN8_ENTER];
+ else if (state.ufs_state == PHY_UFS_HIBERN8_EXIT)
+ cfg = ufs_phy->cfgs_hibern8[CFG_PRE_HIBERN8_EXIT];
+ else
+ goto err_out;
+
+ for_each_phy_cfg(cfg) {
+ for_each_phy_lane(ufs_phy, i) {
+ samsung_ufs_phy_config(ufs_phy, cfg, i);
+ }
+ }
+
+ if (state.ufs_state == PHY_UFS_HIBERN8_EXIT) {
+ for_each_phy_lane(ufs_phy, i) {
+ if (ufs_phy->drvdata->wait_for_cdr) {
+ err = ufs_phy->drvdata->wait_for_cdr(phy, i);
+ if (err)
+ goto err_out;
+ }
+ }
+ }
+
+ return 0;
+err_out:
+ return err;
+}
+
static int samsung_ufs_phy_exit(struct phy *phy)
{
struct samsung_ufs_phy *ss_phy = get_samsung_ufs_phy(phy);
@@ -233,6 +271,7 @@ static const struct phy_ops samsung_ufs_phy_ops = {
.power_off = samsung_ufs_phy_power_off,
.calibrate = samsung_ufs_phy_calibrate,
.set_mode = samsung_ufs_phy_set_mode,
+ .notify_phystate = samsung_ufs_phy_notify_state,
.owner = THIS_MODULE,
};
@@ -287,6 +326,7 @@ static int samsung_ufs_phy_probe(struct platform_device *pdev)
phy->dev = dev;
phy->drvdata = drvdata;
phy->cfgs = drvdata->cfgs;
+ phy->cfgs_hibern8 = drvdata->cfgs_hibern8;
memcpy(&phy->isol, &drvdata->isol, sizeof(phy->isol));
if (!of_property_read_u32_index(dev->of_node, "samsung,pmu-syscon", 1,