@@ -4121,6 +4121,11 @@ static int ufshcd_disable_tx_lcc(struct ufs_hba *hba, bool peer)
return err;
}
+static inline int ufshcd_disable_host_tx_lcc(struct ufs_hba *hba)
+{
+ return ufshcd_disable_tx_lcc(hba, false);
+}
+
static inline int ufshcd_disable_device_tx_lcc(struct ufs_hba *hba)
{
return ufshcd_disable_tx_lcc(hba, true);
@@ -4175,6 +4180,17 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
ufshcd_dme_set(hba, UIC_ARG_MIB(TX_LCC_ENABLE), 1);
}
+ if (hba->quirks & UFSHCD_BROKEN_LCC_PROCESSING_ON_HOST) {
+ ret = ufshcd_disable_device_tx_lcc(hba);
+ if (ret)
+ goto out;
+ }
+
+ if (hba->quirks & UFSHCD_BROKEN_LCC_PROCESSING_ON_DEVICE) {
+ ret = ufshcd_disable_host_tx_lcc(hba);
+ if (ret)
+ goto out;
+ }
if (link_startup_again) {
link_startup_again = false;
retries = DME_LINKSTARTUP_RETRIES;
@@ -591,6 +591,17 @@ struct ufs_hba {
*/
#define UFSHCD_QUIRK_PRDT_BYTE_GRAN 0x80
+ /*
+ * If UFS device is having issue in processing LCC (Line Control
+ * Command) coming from UFS host controller then enable this quirk.
+ * When this quirk is enabled, host controller driver should disable
+ * the LCC transmission on UFS host controller (by clearing
+ * TX_LCC_ENABLE attribute of host to 0).
+ */
+ #define UFSHCD_BROKEN_LCC_PROCESSING_ON_DEVICE 0x100
+
+ #define UFSHCD_BROKEN_LCC_PROCESSING_ON_HOST 0x200
+
unsigned int quirks; /* Deviations from standard UFSHCI spec. */
/* Device deviations from standard UFS device spec. */