Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit ab3e3b4b authored by Asutosh Das's avatar Asutosh Das
Browse files

scsi: ufs: Fixes line-reset and adapt sequence



Fix adapt sequence for G4 and don't dump registers
on Line-reset.

Change-Id: Ibbe09d75c1655d2400878305e7b38e7e2f744e52
Signed-off-by: default avatarAsutosh Das <asutoshd@codeaurora.org>
parent 19a5a7fa
Loading
Loading
Loading
Loading
+67 −13
Original line number Diff line number Diff line
@@ -1380,6 +1380,46 @@ static void ufs_qcom_dev_ref_clk_ctrl(struct ufs_qcom_host *host, bool enable)
	}
}

#if defined(CONFIG_SCSI_UFSHCD_QTI)
static void ufs_qcom_set_adapt(struct ufs_hba *hba)
{
	u32 peer_rx_hs_adapt_initial_cap;
	int ret;

	ret = ufshcd_dme_peer_get(hba,
			  UIC_ARG_MIB_SEL(RX_HS_ADAPT_INITIAL_CAPABILITY,
					  UIC_ARG_MPHY_RX_GEN_SEL_INDEX(0)),
				  &peer_rx_hs_adapt_initial_cap);
	if (ret) {
		dev_err(hba->dev,
			"%s: RX_HS_ADAPT_INITIAL_CAP get failed %d\n",
			__func__, ret);
		peer_rx_hs_adapt_initial_cap =
			PA_PEERRXHSADAPTINITIAL_Default;
	}

	ret = ufshcd_dme_set(hba, UIC_ARG_MIB(PA_PEERRXHSADAPTINITIAL),
			     peer_rx_hs_adapt_initial_cap);
	if (ret)
		dev_err(hba->dev,
			"%s: PA_PEERRXHSADAPTINITIAL set failed %d\n",
			__func__, ret);

	/* INITIAL ADAPT */
	ufshcd_dme_set(hba,
		       UIC_ARG_MIB(PA_TXHSADAPTTYPE),
		       PA_INITIAL_ADAPT);
}
#else
static void ufs_qcom_set_adapt(struct ufs_hba *hba)
{
	/* INITIAL ADAPT */
	ufshcd_dme_set(hba,
		       UIC_ARG_MIB(PA_TXHSADAPTTYPE),
		       PA_INITIAL_ADAPT);
}
#endif

static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
				enum ufs_notify_change_status status,
				struct ufs_pa_layer_attr *dev_max_params,
@@ -1450,19 +1490,14 @@ static int ufs_qcom_pwr_change_notify(struct ufs_hba *hba,
			ufshcd_is_hs_mode(dev_req_params))
			ufs_qcom_dev_ref_clk_ctrl(host, true);

		if (host->hw_ver.major >= 0x4) {
			if (dev_req_params->gear_tx == UFS_HS_G4) {
				/* INITIAL ADAPT */
				ufshcd_dme_set(hba,
					       UIC_ARG_MIB(PA_TXHSADAPTTYPE),
					       PA_INITIAL_ADAPT);
			} else {
		if ((host->hw_ver.major >= 0x4) &&
		    (dev_req_params->gear_tx == UFS_HS_G4))
			ufs_qcom_set_adapt(hba);
		else
			/* NO ADAPT */
			ufshcd_dme_set(hba,
				       UIC_ARG_MIB(PA_TXHSADAPTTYPE),
				       PA_NO_ADAPT);
			}
		}
		break;
	case POST_CHANGE:
		if (ufs_qcom_cfg_timers(hba, dev_req_params->gear_rx,
@@ -2768,6 +2803,24 @@ static void ufs_qcom_print_utp_hci_testbus(struct ufs_hba *hba)
	kfree(testbus);
}

static void ufshcd_print_fsm_state(struct ufs_hba *hba)
{
	int err = 0, tx_fsm_val = 0, rx_fsm_val = 0;

	err = ufshcd_dme_get(hba,
			     UIC_ARG_MIB_SEL(MPHY_TX_FSM_STATE,
					     UIC_ARG_MPHY_TX_GEN_SEL_INDEX(0)),
			     &tx_fsm_val);
	dev_err(hba->dev, "%s: TX_FSM_STATE = %u, err = %d\n", __func__,
		tx_fsm_val, err);
	err = ufshcd_dme_get(hba,
			     UIC_ARG_MIB_SEL(MPHY_RX_FSM_STATE,
					     UIC_ARG_MPHY_RX_GEN_SEL_INDEX(0)),
			     &rx_fsm_val);
	dev_err(hba->dev, "%s: RX_FSM_STATE = %u, err = %d\n", __func__,
		rx_fsm_val, err);
}

static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)
{
	struct ufs_qcom_host *host = ufshcd_get_variant(hba);
@@ -2791,6 +2844,7 @@ static void ufs_qcom_dump_dbg_regs(struct ufs_hba *hba)
		usleep_range(1000, 1100);
		ufs_qcom_phy_dbg_register_dump(phy);
	}
	ufshcd_print_fsm_state(hba);
}

/*
+13 −0
Original line number Diff line number Diff line
@@ -58,8 +58,13 @@
#define UFSHCD_ENABLE_INTRS	(UTP_TRANSFER_REQ_COMPL |\
				 UTP_TASK_REQ_COMPL |\
				 UFSHCD_ERROR_MASK)
#if defined(CONFIG_SCSI_UFSHCD_QTI)
/* UIC command timeout, unit: ms */
#define UIC_CMD_TIMEOUT	999
#else
/* UIC command timeout, unit: ms */
#define UIC_CMD_TIMEOUT	500
#endif

/* NOP OUT retries waiting for NOP IN response */
#define NOP_OUT_RETRIES    10
@@ -5849,6 +5854,10 @@ static irqreturn_t ufshcd_update_uic_error(struct ufs_hba *hba)

	/* PHY layer lane error */
	reg = ufshcd_readl(hba, REG_UIC_ERROR_CODE_PHY_ADAPTER_LAYER);
#if defined(CONFIG_SCSI_UFSHCD_QTI)
	if (reg & UIC_PHY_ADAPTER_LAYER_GENERIC_ERROR)
		dev_err(hba->dev, "line-reset: 0x%08x\n", reg);
#endif
	/* Ignore LINERESET indication, as this is not an error */
	if ((reg & UIC_PHY_ADAPTER_LAYER_ERROR) &&
	    (reg & UIC_PHY_ADAPTER_LAYER_LANE_ERR_MASK)) {
@@ -6096,6 +6105,10 @@ static irqreturn_t ufshcd_intr(int irq, void *__hba)
		if (enabled_intr_status)
			retval |= ufshcd_sl_intr(hba, enabled_intr_status);

#if defined(CONFIG_SCSI_UFSHCD_QTI)
		if (enabled_intr_status)
			retval = IRQ_HANDLED;
#endif
		intr_status = ufshcd_readl(hba, REG_INTERRUPT_STATUS);
	} while (intr_status && --retries);

+2 −2
Original line number Diff line number Diff line
@@ -941,9 +941,9 @@ struct ufs_hba {
#endif

#ifdef CONFIG_SCSI_UFSHCD_QTI
#define UFSHCD_CAP_POWER_COLLAPSE_DURING_HIBERN8 (1 << 7)
#define UFSHCD_CAP_POWER_COLLAPSE_DURING_HIBERN8 (1 << 8)
	/* Allow standalone Hibern8 enter on idle */
#define UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE (1 << 5)
#define UFSHCD_CAP_HIBERN8_ENTER_ON_IDLE (1 << 9)
	struct rw_semaphore lock;
	/* Bitmask for enabling debug prints */
	u32 ufshcd_dbg_print;