summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSubhash Jadavani <subhashj@codeaurora.org>2013-08-28 20:27:20 +0530
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-22 10:55:24 -0700
commit893e612aeb23d4154a55772360bd12c1f9f4409b (patch)
tree207e74b874fa65915aa38c080a34d8d8cfda2b80
parente5b8f6757e3fbebaec3a07b81d176dabe25b34c3 (diff)
scsi: ufs-msm: advertise deviations from UFSHCI standard spec
HIBERN8 & Interrupt aggregation feature is broken on MSM UFS controller HW revision 1.1.0 hence this patch advertise UFSHCD_QUIRK_BROKEN_HIBERN8 & UFSHCD_QUIRK_BROKEN_INTR_AGGR quirks to standard UFSHCD driver. Change-Id: I14f063f5802c7dce95e4fd41a9edcb2ed566caa6 Signed-off-by: Subhash Jadavani <subhashj@codeaurora.org>
-rw-r--r--drivers/scsi/ufs/ufs-msm.c37
1 files changed, 37 insertions, 0 deletions
diff --git a/drivers/scsi/ufs/ufs-msm.c b/drivers/scsi/ufs/ufs-msm.c
index 84ad6400b313..327ee18cb68b 100644
--- a/drivers/scsi/ufs/ufs-msm.c
+++ b/drivers/scsi/ufs/ufs-msm.c
@@ -1287,6 +1287,41 @@ static int msm_ufs_link_startup_notify(struct ufs_hba *hba, bool status)
return 0;
}
+#define UFS_HW_VER_MAJOR_SHFT (28)
+#define UFS_HW_VER_MAJOR_MASK (0x000F << UFS_HW_VER_MAJOR_SHFT)
+#define UFS_HW_VER_MINOR_SHFT (16)
+#define UFS_HW_VER_MINOR_MASK (0x0FFF << UFS_HW_VER_MINOR_SHFT)
+#define UFS_HW_VER_STEP_SHFT (0)
+#define UFS_HW_VER_STEP_MASK (0xFFFF << UFS_HW_VER_STEP_SHFT)
+
+/**
+ * msm_ufs_advertise_quirks - advertise the known MSM UFS controller quirks
+ * @hba: host controller instance
+ *
+ * MSM UFS host controller might have some non standard behaviours (quirks)
+ * than what is specified by UFSHCI specification. Advertise all such
+ * quirks to standard UFS host controller driver so standard takes them into
+ * account.
+ */
+static void msm_ufs_advertise_quirks(struct ufs_hba *hba)
+{
+ u32 ver = ufshcd_readl(hba, REG_UFS_HW_VERSION);
+ u8 major;
+ u16 minor, step;
+
+ major = (ver & UFS_HW_VER_MAJOR_MASK) >> UFS_HW_VER_MAJOR_SHFT;
+ minor = (ver & UFS_HW_VER_MINOR_MASK) >> UFS_HW_VER_MINOR_SHFT;
+ step = (ver & UFS_HW_VER_STEP_MASK) >> UFS_HW_VER_STEP_SHFT;
+
+ /*
+ * Interrupt aggregation and HIBERN8 on UFS HW controller revision 1.1.0
+ * is broken.
+ */
+ if ((major == 0x1) && (minor == 0x001) && (step == 0x0000))
+ hba->quirks |= (UFSHCD_QUIRK_BROKEN_INTR_AGGR
+ | UFSHCD_QUIRK_BROKEN_HIBERN8);
+}
+
/**
* msm_ufs_init - bind phy with controller
* @hba: host controller instance
@@ -1312,6 +1347,8 @@ static int msm_ufs_init(struct ufs_hba *hba)
err = msm_ufs_phy_power_on(phy);
if (err)
hba->priv = NULL;
+
+ msm_ufs_advertise_quirks(hba);
out:
return err;
}