summaryrefslogtreecommitdiffstats
path: root/drivers/scsi/ufs
diff options
context:
space:
mode:
authorYaniv Gardi <ygardi@codeaurora.org>2015-05-17 11:54:59 -0400
committerJames Bottomley <JBottomley@Odin.com>2015-06-02 16:14:39 -0400
commit7ca38cf300eb7fba9010d847baa6a4f5c458dd4e (patch)
tree9a0202197e763a3cfac3acaf100c602b94de9fe0 /drivers/scsi/ufs
parent81c7e06a5ffcca8ac8bbaa2422051bf1d7a87a46 (diff)
scsi: ufs: provide a quirk to disable the LCC
LCC (Line Control Command) are being used for communication between UFS host and UFS device. New commercial UFS devices don't have the issues with LCC processing but UFS host controller might still have the issue with LCC processing, hence, added a routine to disable TX LCC on the device. Signed-off-by: Yaniv Gardi <ygardi@codeaurora.org> Reviewed-by: Akinobu Mita <akinobu.mita@gmail.com> Signed-off-by: James Bottomley <JBottomley@Odin.com>
Diffstat (limited to 'drivers/scsi/ufs')
-rw-r--r--drivers/scsi/ufs/ufshcd.c42
-rw-r--r--drivers/scsi/ufs/ufshcd.h8
-rw-r--r--drivers/scsi/ufs/ufshci.h3
3 files changed, 53 insertions, 0 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 9641bcb90cd2..3e57cca1ef33 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -2640,6 +2640,42 @@ static int ufshcd_hba_enable(struct ufs_hba *hba)
2640 return 0; 2640 return 0;
2641} 2641}
2642 2642
2643static int ufshcd_disable_tx_lcc(struct ufs_hba *hba, bool peer)
2644{
2645 int tx_lanes, i, err = 0;
2646
2647 if (!peer)
2648 ufshcd_dme_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES),
2649 &tx_lanes);
2650 else
2651 ufshcd_dme_peer_get(hba, UIC_ARG_MIB(PA_CONNECTEDTXDATALANES),
2652 &tx_lanes);
2653 for (i = 0; i < tx_lanes; i++) {
2654 if (!peer)
2655 err = ufshcd_dme_set(hba,
2656 UIC_ARG_MIB_SEL(TX_LCC_ENABLE,
2657 UIC_ARG_MPHY_TX_GEN_SEL_INDEX(i)),
2658 0);
2659 else
2660 err = ufshcd_dme_peer_set(hba,
2661 UIC_ARG_MIB_SEL(TX_LCC_ENABLE,
2662 UIC_ARG_MPHY_TX_GEN_SEL_INDEX(i)),
2663 0);
2664 if (err) {
2665 dev_err(hba->dev, "%s: TX LCC Disable failed, peer = %d, lane = %d, err = %d",
2666 __func__, peer, i, err);
2667 break;
2668 }
2669 }
2670
2671 return err;
2672}
2673
2674static inline int ufshcd_disable_device_tx_lcc(struct ufs_hba *hba)
2675{
2676 return ufshcd_disable_tx_lcc(hba, true);
2677}
2678
2643/** 2679/**
2644 * ufshcd_link_startup - Initialize unipro link startup 2680 * ufshcd_link_startup - Initialize unipro link startup
2645 * @hba: per adapter instance 2681 * @hba: per adapter instance
@@ -2677,6 +2713,12 @@ static int ufshcd_link_startup(struct ufs_hba *hba)
2677 /* failed to get the link up... retire */ 2713 /* failed to get the link up... retire */
2678 goto out; 2714 goto out;
2679 2715
2716 if (hba->quirks & UFSHCD_QUIRK_BROKEN_LCC) {
2717 ret = ufshcd_disable_device_tx_lcc(hba);
2718 if (ret)
2719 goto out;
2720 }
2721
2680 /* Include any host controller configuration via UIC commands */ 2722 /* Include any host controller configuration via UIC commands */
2681 if (hba->vops && hba->vops->link_startup_notify) { 2723 if (hba->vops && hba->vops->link_startup_notify) {
2682 ret = hba->vops->link_startup_notify(hba, POST_CHANGE); 2724 ret = hba->vops->link_startup_notify(hba, POST_CHANGE);
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index fc8bec9960b1..b845f1535f29 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -426,6 +426,14 @@ struct ufs_hba {
426 */ 426 */
427 #define UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS UFS_BIT(1) 427 #define UFSHCD_QUIRK_DELAY_BEFORE_DME_CMDS UFS_BIT(1)
428 428
429 /*
430 * If UFS host controller is having issue in processing LCC (Line
431 * Control Command) coming from device then enable this quirk.
432 * When this quirk is enabled, host controller driver should disable
433 * the LCC transmission on UFS device (by clearing TX_LCC_ENABLE
434 * attribute of device to 0).
435 */
436 #define UFSHCD_QUIRK_BROKEN_LCC UFS_BIT(2)
429 437
430 unsigned int quirks; /* Deviations from standard UFSHCI spec. */ 438 unsigned int quirks; /* Deviations from standard UFSHCI spec. */
431 439
diff --git a/drivers/scsi/ufs/ufshci.h b/drivers/scsi/ufs/ufshci.h
index d5721199e9cc..f8909ece2171 100644
--- a/drivers/scsi/ufs/ufshci.h
+++ b/drivers/scsi/ufs/ufshci.h
@@ -206,6 +206,9 @@ enum {
206#define CONFIG_RESULT_CODE_MASK 0xFF 206#define CONFIG_RESULT_CODE_MASK 0xFF
207#define GENERIC_ERROR_CODE_MASK 0xFF 207#define GENERIC_ERROR_CODE_MASK 0xFF
208 208
209/* GenSelectorIndex calculation macros for M-PHY attributes */
210#define UIC_ARG_MPHY_TX_GEN_SEL_INDEX(lane) (lane)
211
209#define UIC_ARG_MIB_SEL(attr, sel) ((((attr) & 0xFFFF) << 16) |\ 212#define UIC_ARG_MIB_SEL(attr, sel) ((((attr) & 0xFFFF) << 16) |\
210 ((sel) & 0xFFFF)) 213 ((sel) & 0xFFFF))
211#define UIC_ARG_MIB(attr) UIC_ARG_MIB_SEL(attr, 0) 214#define UIC_ARG_MIB(attr) UIC_ARG_MIB_SEL(attr, 0)