scsi: ufs: amend ufs host for exynos8890 evt1
authorhgchu <hg.chu@samsung.com>
Fri, 12 Jan 2018 00:34:19 +0000 (09:34 +0900)
committerJaeHun Jung <jh0801.jung@samsung.com>
Tue, 8 May 2018 08:20:09 +0000 (17:20 +0900)
Change-Id: Ic77815f6364bf42af7b7c51f410fcf6f51e7c980
Signed-off-by: hgchu <hg.chu@samsung.com>
drivers/scsi/ufs/mphy.h [new file with mode: 0644]
drivers/scsi/ufs/ufshcd.c
drivers/scsi/ufs/ufshcd.h
drivers/scsi/ufs/ufshci.h

diff --git a/drivers/scsi/ufs/mphy.h b/drivers/scsi/ufs/mphy.h
new file mode 100644 (file)
index 0000000..093697a
--- /dev/null
@@ -0,0 +1,37 @@
+/*
+ * drivers/scsi/ufs/mphy.h
+ *
+ * Copyright (C) 2014 Samsung Electronics Co., Ltd.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ */
+
+#ifndef _MPHY_H_
+#define _MPHY_H_
+
+#define TX_HIBERN8TIME_CAP             0x0f
+#define TX_MIN_ACTIVATE_TIME           0x33
+
+#define RX_HS_G1_SYNC_LENGTH_CAP       0x8b
+#define RX_HS_G1_PREP_LENGTH_CAP       0x8c
+#define RX_HS_G2_SYNC_LENGTH_CAP       0x94
+#define RX_HS_G3_SYNC_LENGTH_CAP       0x95
+#define RX_HS_G2_PREP_LENGTH_CAP       0x96
+#define RX_HS_G3_PREP_LENGTH_CAP       0x97
+ #define SYNC_RANGE_FINE       (0 << 6)
+ #define SYNC_RANGE_COARSE     (1 << 6)
+ #define SYNC_LEN(x)           ((x) & 0x3f)
+ #define PREP_LEN(x)           ((x) & 0xf)
+#define RX_ADV_GRANULARITY_CAP         0x98
+ #define RX_ADV_FINE_GRAN_STEP(x)      ((((x) & 0x3) << 1) | 0x1)
+#define TX_ADV_GRANULARITY_CAP         0x10
+ #define TX_ADV_FINE_GRAN_STEP(x)      ((((x) & 0x3) << 1) | 0x1)
+#define RX_MIN_ACTIVATETIME_CAP                0x8f
+#define RX_HIBERN8TIME_CAP             0x92
+#define RX_ADV_HIBERN8TIME_CAP         0x99
+#define RX_ADV_MIN_ACTIVATETIME_CAP    0x9a
+
+#endif /* _MPHY_H_ */
index d10b52c0cf56f1877d2e53d6d6c13f1207719015..fe59415b5ad1eea5dbbc55e174695015bff64fb7 100644 (file)
 #define MASK_QUERY_UPIU_FLAG_LOC 0xFF
 
 /* Interrupt aggregation default timeout, unit: 40us */
-#define INT_AGGR_DEF_TO        0x02
+#define INT_AGGR_DEF_TO        0x01
+
+/* Link Hibernation delay, msecs */
+#define LINK_H8_DELAY  20
+
 
 #define ufshcd_toggle_vreg(_dev, _vreg, _on)                           \
        ({                                                              \
@@ -231,8 +235,6 @@ static void ufshcd_suspend_clkscaling(struct ufs_hba *hba);
 static void __ufshcd_suspend_clkscaling(struct ufs_hba *hba);
 static int ufshcd_scale_clks(struct ufs_hba *hba, bool scale_up);
 static irqreturn_t ufshcd_intr(int irq, void *__hba);
-static int ufshcd_config_pwr_mode(struct ufs_hba *hba,
-               struct ufs_pa_layer_attr *desired_pwr_mode);
 static int ufshcd_change_power_mode(struct ufs_hba *hba,
                             struct ufs_pa_layer_attr *pwr_mode);
 static inline bool ufshcd_valid_tag(struct ufs_hba *hba, int tag)
@@ -3431,6 +3433,37 @@ static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba)
        usleep_range(min_sleep_time_us, min_sleep_time_us + 50);
 }
 
+static int ufshcd_dme_reset(struct ufs_hba *hba)
+{
+       struct uic_command uic_cmd = {0};
+       int ret;
+
+       uic_cmd.command = UIC_CMD_DME_RESET;
+       uic_cmd.argument1 = 0x1;
+
+       ret = ufshcd_send_uic_cmd(hba, &uic_cmd);
+       if (ret)
+               dev_err(hba->dev,
+                       "dme-reset: error code %d\n", ret);
+
+       return ret;
+}
+
+static int ufshcd_dme_enable(struct ufs_hba *hba)
+{
+       struct uic_command uic_cmd = {0};
+       int ret;
+
+       uic_cmd.command = UIC_CMD_DME_ENABLE;
+
+       ret = ufshcd_send_uic_cmd(hba, &uic_cmd);
+       if (ret)
+               dev_err(hba->dev,
+                       "dme-enable: error code %d\n", ret);
+
+       return ret;
+}
+
 /**
  * ufshcd_dme_set_attr - UIC command for DME_SET, DME_PEER_SET
  * @hba: per adapter instance
@@ -3910,7 +3943,7 @@ static int ufshcd_change_power_mode(struct ufs_hba *hba,
  * @hba: per-adapter instance
  * @desired_pwr_mode: desired power configuration
  */
-static int ufshcd_config_pwr_mode(struct ufs_hba *hba,
+int ufshcd_config_pwr_mode(struct ufs_hba *hba,
                struct ufs_pa_layer_attr *desired_pwr_mode)
 {
        struct ufs_pa_layer_attr final_params = { 0 };
@@ -3928,6 +3961,7 @@ static int ufshcd_config_pwr_mode(struct ufs_hba *hba,
 
        return ret;
 }
+EXPORT_SYMBOL_GPL(ufshcd_config_pwr_mode);
 
 /**
  * ufshcd_complete_dev_init() - checks device readiness
@@ -4045,7 +4079,7 @@ static inline void ufshcd_hba_stop(struct ufs_hba *hba, bool can_sleep)
 }
 
 /**
- * ufshcd_hba_enable - initialize the controller
+ * _ufshcd_hba_enable - initialize the controller
  * @hba: per adapter instance
  *
  * The controller resets itself and controller firmware initialization
@@ -4054,7 +4088,7 @@ static inline void ufshcd_hba_stop(struct ufs_hba *hba, bool can_sleep)
  *
  * Returns 0 on success, non-zero value on failure
  */
-static int ufshcd_hba_enable(struct ufs_hba *hba)
+static int __ufshcd_hba_enable(struct ufs_hba *hba)
 {
        int retry;
 
@@ -4145,6 +4179,24 @@ static inline int ufshcd_disable_device_tx_lcc(struct ufs_hba *hba)
        return ufshcd_disable_tx_lcc(hba, true);
 }
 
+static int ufshcd_hba_enable(struct ufs_hba *hba)
+{
+       int ret;
+       if (hba->vops && hba->vops->host_reset)
+               hba->vops->host_reset(hba);
+       if (hba->quirks & UFSHCD_QUIRK_USE_OF_HCE) {
+               /* enable UIC related interrupts */
+               ufshcd_enable_intr(hba, UFSHCD_UIC_MASK);
+
+               ret = ufshcd_dme_reset(hba);
+               if (!ret)
+                       ret = ufshcd_dme_enable(hba);
+       } else {
+               ret = __ufshcd_hba_enable(hba);
+       }
+       return ret;
+}
+
 /**
  * ufshcd_link_startup - Initialize unipro link startup
  * @hba: per adapter instance
@@ -4405,6 +4457,7 @@ static int ufshcd_slave_configure(struct scsi_device *sdev)
 
        blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1);
        blk_queue_max_segment_size(q, PRDT_DATA_BYTE_COUNT_MAX);
+       blk_queue_update_dma_alignment(q, PAGE_SIZE - 1);
 
        return 0;
 }
@@ -4521,6 +4574,7 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
 
        switch (ocs) {
        case OCS_SUCCESS:
+       case OCS_FATAL_ERROR:
                result = ufshcd_get_req_rsp(lrbp->ucd_rsp_ptr);
                hba->ufs_stats.last_hibern8_exit_tstamp = ktime_set(0, 0);
                switch (result) {
@@ -4579,7 +4633,6 @@ ufshcd_transfer_rsp_status(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
        case OCS_MISMATCH_DATA_BUF_SIZE:
        case OCS_MISMATCH_RESP_UPIU_SIZE:
        case OCS_PEER_COMM_FAILURE:
-       case OCS_FATAL_ERROR:
        default:
                result |= DID_ERROR << 16;
                dev_err(hba->dev,
@@ -6339,9 +6392,11 @@ static void ufshcd_def_desc_sizes(struct ufs_hba *hba)
 static int ufshcd_probe_hba(struct ufs_hba *hba)
 {
        struct ufs_dev_desc card = {0};
+       int re_cnt = 0;
        int ret;
        ktime_t start = ktime_get();
 
+retry:
        ret = ufshcd_link_startup(hba);
        if (ret)
                goto out;
@@ -6452,6 +6507,9 @@ static int ufshcd_probe_hba(struct ufs_hba *hba)
                hba->is_init_prefetch = true;
 
 out:
+       if (ret) {
+               goto retry;
+       }
        /*
         * If we failed to initialize the device or the device is not
         * present, turn off the power/clocks etc.
index 96d579b1257cf298e05c05b2b9114628f8975670..08ddfe39ad129e279ef7135448f9f6a739050f20 100644 (file)
@@ -325,8 +325,7 @@ struct ufs_hba_variant_ops {
                                        struct ufs_pa_layer_attr *);
        void    (*setup_xfer_req)(struct ufs_hba *, int, bool);
        void    (*setup_task_mgmt)(struct ufs_hba *, int, u8);
-       void    (*hibern8_notify)(struct ufs_hba *, enum uic_cmd_dme,
-                                       enum ufs_notify_change_status);
+       void    (*hibern8_notify)(struct ufs_hba *, u8, bool);
        int     (*apply_dev_quirks)(struct ufs_hba *);
        int     (*suspend)(struct ufs_hba *, enum ufs_pm_op);
        int     (*resume)(struct ufs_hba *, enum ufs_pm_op);
@@ -538,7 +537,7 @@ struct ufs_hba {
        int pm_op_in_progress;
 
        struct ufshcd_lrb *lrb;
-       unsigned long lrb_in_use;
+       volatile unsigned long lrb_in_use;
 
        unsigned long outstanding_tasks;
        unsigned long outstanding_reqs;
@@ -599,6 +598,7 @@ struct ufs_hba {
         */
        #define UFSHCD_QUIRK_PRDT_BYTE_GRAN                     UFS_BIT(7)
 
+       #define UFSHCD_QUIRK_USE_OF_HCE                         UFS_BIT(8)
        unsigned int quirks;    /* Deviations from standard UFSHCI spec. */
 
        /* Device deviations from standard UFS device spec. */
@@ -793,6 +793,8 @@ extern int ufshcd_dme_set_attr(struct ufs_hba *hba, u32 attr_sel,
                               u8 attr_set, u32 mib_val, u8 peer);
 extern int ufshcd_dme_get_attr(struct ufs_hba *hba, u32 attr_sel,
                               u32 *mib_val, u8 peer);
+extern int ufshcd_config_pwr_mode(struct ufs_hba *hba,
+               struct ufs_pa_layer_attr *desired_pwr_mode);
 
 /* UIC command interfaces for DME primitives */
 #define DME_LOCAL      0
index d338a851c393bcfb6a150dfbb74133b36c60aa8f..37004df6d79debea539492c631e19e779087e834 100644 (file)
@@ -197,10 +197,20 @@ enum {
 /* UECN - Host UIC Error Code Network Layer 40h */
 #define UIC_NETWORK_LAYER_ERROR                        UFS_BIT(31)
 #define UIC_NETWORK_LAYER_ERROR_CODE_MASK      0x7
+#define UIC_NETWORK_UNSUPPORTED_HEADER_TYPE    BIT(0)
+#define UIC_NETWORK_BAD_DEVICEID_ENC           BIT(1)
+#define UIC_NETWORK_LHDR_TRAP_PACKET_DROPPING  BIT(2)
 
 /* UECT - Host UIC Error Code Transport Layer 44h */
 #define UIC_TRANSPORT_LAYER_ERROR              UFS_BIT(31)
 #define UIC_TRANSPORT_LAYER_ERROR_CODE_MASK    0x7F
+#define UIC_TRANSPORT_UNSUPPORTED_HEADER_TYPE  BIT(0)
+#define UIC_TRANSPORT_UNKNOWN_CPORTID          BIT(1)
+#define UIC_TRANSPORT_NO_CONNECTION_RX         BIT(2)
+#define UIC_TRANSPORT_CONTROLLED_SEGMENT_DROPPING      BIT(3)
+#define UIC_TRANSPORT_BAD_TC                   BIT(4)
+#define UIC_TRANSPORT_E2E_CREDIT_OVERFOW       BIT(5)
+#define UIC_TRANSPORT_SAFETY_VALUE_DROPPING    BIT(6)
 
 /* UECDME - Host UIC Error Code DME 48h */
 #define UIC_DME_ERROR                  UFS_BIT(31)