summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubhash Jadavani <subhashj@codeaurora.org>2015-01-16 17:23:24 -0800
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 10:58:36 -0700
commit2d59afeff93bec2f5892093a7ed0ad879fcf4295 (patch)
tree1f40cdb9a3ceeaf52c30aa45d43fd67b18f165d6
parent4ad04d8bc587f53e654817caa206043f7eefb766 (diff)
scsi: ufs: add UFS power collapse support during hibern8
UFS host controller hardware may allow the host controller to be power collapsed when UFS link is hibern8 state, this change allows the UFS host controller to be power collapsed during hibern8. Change-Id: I42f962484b9d6635be1139b1fc6447dd2ca2200c Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> [subhashj@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org> [venkatg@codeaurora.org: resolved trivial merge conflicts] Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
-rw-r--r--drivers/scsi/ufs/ufs-qcom.c12
-rw-r--r--drivers/scsi/ufs/ufshcd.c8
-rw-r--r--include/linux/scsi/ufs/ufshcd.h14
3 files changed, 26 insertions, 8 deletions
diff --git a/drivers/scsi/ufs/ufs-qcom.c b/drivers/scsi/ufs/ufs-qcom.c
index f3e2fde8b4c0..8ed0109cfa71 100644
--- a/drivers/scsi/ufs/ufs-qcom.c
+++ b/drivers/scsi/ufs/ufs-qcom.c
@@ -968,8 +968,14 @@ static void ufs_qcom_set_caps(struct ufs_hba *hba)
ufs_qcom_get_controller_revision(hba, &major, &minor, &step);
- if (major >= 0x2)
+ hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_CLK_SCALING;
+ hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
+ hba->caps |= UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE;
+
+ if (host->hw_ver.major >= 0x2) {
+ hba->caps |= UFSHCD_CAP_POWER_COLLAPSE_DURING_HIBERN8;
host->caps = UFS_QCOM_CAP_QUNIPRO;
+ }
}
static int ufs_qcom_get_bus_vote(struct ufs_qcom_host *host,
@@ -1288,10 +1294,6 @@ static int ufs_qcom_init(struct ufs_hba *hba)
ufs_qcom_set_caps(hba);
ufs_qcom_advertise_quirks(hba);
- hba->caps |= UFSHCD_CAP_CLK_GATING |
- UFSHCD_CAP_HIBERN8_WITH_CLK_GATING;
- hba->caps |= UFSHCD_CAP_AUTO_BKOPS_SUSPEND;
- hba->caps |= UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE;
ufs_qcom_setup_clocks(hba, true);
if (hba->dev->id < MAX_UFS_QCOM_HOSTS)
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index a58d337d62bf..9ce383109ad9 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -7319,13 +7319,17 @@ out:
static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba)
{
- if (ufshcd_is_link_off(hba))
+ if (ufshcd_is_link_off(hba) ||
+ (ufshcd_is_link_hibern8(hba)
+ && ufshcd_is_power_collapse_during_hibern8_allowed(hba)))
ufshcd_setup_hba_vreg(hba, false);
}
static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba)
{
- if (ufshcd_is_link_off(hba))
+ if (ufshcd_is_link_off(hba) ||
+ (ufshcd_is_link_hibern8(hba)
+ && ufshcd_is_power_collapse_during_hibern8_allowed(hba)))
ufshcd_setup_hba_vreg(hba, true);
}
diff --git a/include/linux/scsi/ufs/ufshcd.h b/include/linux/scsi/ufs/ufshcd.h
index ad3d250a7018..5e17d1b26a98 100644
--- a/include/linux/scsi/ufs/ufshcd.h
+++ b/include/linux/scsi/ufs/ufshcd.h
@@ -794,7 +794,12 @@ struct ufs_hba {
* to do background operation when it's active but it might degrade
* the performance of ongoing read/write operations.
*/
-#define UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND (1 << 5)
+#define UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND (1 << 6)
+ /*
+ * If host controller hardware can be power collapsed when UFS link is
+ * in hibern8 then enable this cap.
+ */
+#define UFSHCD_CAP_POWER_COLLAPSE_DURING_HIBERN8 (1 << 7)
struct devfreq *devfreq;
struct ufs_clk_scaling clk_scaling;
@@ -822,6 +827,13 @@ static inline bool ufshcd_is_hibern8_on_idle_allowed(struct ufs_hba *hba)
{
return hba->caps & UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE;
}
+
+static inline bool ufshcd_is_power_collapse_during_hibern8_allowed(
+ struct ufs_hba *hba)
+{
+ return !!(hba->caps & UFSHCD_CAP_POWER_COLLAPSE_DURING_HIBERN8);
+}
+
static inline bool ufshcd_keep_autobkops_enabled_except_suspend(
struct ufs_hba *hba)
{