From ce32edf88ce4c1408c498f883e4d7fbfdfe58553 Mon Sep 17 00:00:00 2001 From: Can Guo Date: Tue, 20 Aug 2019 00:53:01 -0700 Subject: [PATCH] phy: qcom-ufs: add optional ref aux clk Newer platforms need an additional ref aux clk to be enabled, add support for the new ref aux clk and make it optional as its not needed by other phy versions. Change-Id: I5e04980eb451b193e9c024bfe35383d10d17feff Signed-off-by: Venkat Gopalakrishnan [cang@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Can Guo --- drivers/phy/qualcomm/phy-qcom-ufs-i.h | 1 + drivers/phy/qualcomm/phy-qcom-ufs.c | 32 +++++++++++++++++++++++++++ 2 files changed, 33 insertions(+) diff --git a/drivers/phy/qualcomm/phy-qcom-ufs-i.h b/drivers/phy/qualcomm/phy-qcom-ufs-i.h index 282afa4b5561..5e0c9fc7282c 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs-i.h +++ b/drivers/phy/qualcomm/phy-qcom-ufs-i.h @@ -66,6 +66,7 @@ struct ufs_qcom_phy { struct clk *ref_clk_src; struct clk *ref_clk_parent; struct clk *ref_clk; + struct clk *ref_aux_clk; bool is_ref_clk_enabled; bool is_dev_ref_clk_enabled; struct ufs_qcom_phy_vreg vdda_pll; diff --git a/drivers/phy/qualcomm/phy-qcom-ufs.c b/drivers/phy/qualcomm/phy-qcom-ufs.c index 29806f20f6f1..5baa68ba2401 100644 --- a/drivers/phy/qualcomm/phy-qcom-ufs.c +++ b/drivers/phy/qualcomm/phy-qcom-ufs.c @@ -211,7 +211,15 @@ skip_txrx_clk: err = ufs_qcom_phy_clk_get(phy_common->dev, "ref_clk", &phy_common->ref_clk); + if (err) + goto out; + /* + * "ref_aux_clk" is optional and only supported by certain + * phy versions, don't abort init if it's not found. + */ + __ufs_qcom_phy_clk_get(phy_common->dev, "ref_aux_clk", + &phy_common->ref_aux_clk, false); out: return err; } @@ -389,9 +397,26 @@ static int ufs_qcom_phy_enable_ref_clk(struct ufs_qcom_phy *phy) goto out_disable_parent; } + /* + * "ref_aux_clk" is optional clock and only supported by certain + * phy versions, hence make sure that clk reference is available + * before trying to enable the clock. + */ + if (phy->ref_aux_clk) { + ret = clk_prepare_enable(phy->ref_aux_clk); + if (ret) { + dev_err(phy->dev, "%s: ref_aux_clk enable failed %d\n", + __func__, ret); + goto out_disable_ref; + } + } + phy->is_ref_clk_enabled = true; goto out; +out_disable_ref: + if (phy->ref_clk) + clk_disable_unprepare(phy->ref_clk); out_disable_parent: if (phy->ref_clk_parent) clk_disable_unprepare(phy->ref_clk_parent); @@ -426,6 +451,13 @@ out: static void ufs_qcom_phy_disable_ref_clk(struct ufs_qcom_phy *phy) { if (phy->is_ref_clk_enabled) { + /* + * "ref_aux_clk" is optional clock and only supported by + * certain phy versions, hence make sure that clk reference + * is available before trying to disable the clock. + */ + if (phy->ref_aux_clk) + clk_disable_unprepare(phy->ref_aux_clk); clk_disable_unprepare(phy->ref_clk); /* * "ref_clk_parent" is optional clock hence make sure that clk