Commit dd7143e2 authored by Can Guo's avatar Can Guo Committed by Martin K. Petersen
Browse files

scsi: ufs: Put HBA into LPM during clk gating

parent 3fb52041
Loading
Loading
Loading
Loading
+7 −2
Original line number Original line Diff line number Diff line
@@ -245,6 +245,8 @@ static int ufshcd_wb_buf_flush_disable(struct ufs_hba *hba);
static int ufshcd_wb_ctrl(struct ufs_hba *hba, bool enable);
static int ufshcd_wb_ctrl(struct ufs_hba *hba, bool enable);
static int ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set);
static int ufshcd_wb_toggle_flush_during_h8(struct ufs_hba *hba, bool set);
static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable);
static inline void ufshcd_wb_toggle_flush(struct ufs_hba *hba, bool enable);
static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba);
static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba);


static inline bool ufshcd_valid_tag(struct ufs_hba *hba, int tag)
static inline bool ufshcd_valid_tag(struct ufs_hba *hba, int tag)
{
{
@@ -1548,6 +1550,7 @@ static void ufshcd_ungate_work(struct work_struct *work)
	}
	}


	spin_unlock_irqrestore(hba->host->host_lock, flags);
	spin_unlock_irqrestore(hba->host->host_lock, flags);
	ufshcd_hba_vreg_set_hpm(hba);
	ufshcd_setup_clocks(hba, true);
	ufshcd_setup_clocks(hba, true);


	ufshcd_enable_irq(hba);
	ufshcd_enable_irq(hba);
@@ -1713,6 +1716,8 @@ static void ufshcd_gate_work(struct work_struct *work)
		/* If link is active, device ref_clk can't be switched off */
		/* If link is active, device ref_clk can't be switched off */
		__ufshcd_setup_clocks(hba, false, true);
		__ufshcd_setup_clocks(hba, false, true);


	/* Put the host controller in low power mode if possible */
	ufshcd_hba_vreg_set_lpm(hba);
	/*
	/*
	 * In case you are here to cancel this work the gating state
	 * In case you are here to cancel this work the gating state
	 * would be marked as REQ_CLKS_ON. In this case keep the state
	 * would be marked as REQ_CLKS_ON. In this case keep the state
@@ -8405,13 +8410,13 @@ static int ufshcd_vreg_set_hpm(struct ufs_hba *hba)


static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba)
static void ufshcd_hba_vreg_set_lpm(struct ufs_hba *hba)
{
{
	if (ufshcd_is_link_off(hba))
	if (ufshcd_is_link_off(hba) || ufshcd_can_aggressive_pc(hba))
		ufshcd_setup_hba_vreg(hba, false);
		ufshcd_setup_hba_vreg(hba, false);
}
}


static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba)
static void ufshcd_hba_vreg_set_hpm(struct ufs_hba *hba)
{
{
	if (ufshcd_is_link_off(hba))
	if (ufshcd_is_link_off(hba) || ufshcd_can_aggressive_pc(hba))
		ufshcd_setup_hba_vreg(hba, true);
		ufshcd_setup_hba_vreg(hba, true);
}
}


+13 −0
Original line number Original line Diff line number Diff line
@@ -592,6 +592,13 @@ enum ufshcd_caps {
	 * inline crypto engine, if it is present
	 * inline crypto engine, if it is present
	 */
	 */
	UFSHCD_CAP_CRYPTO				= 1 << 8,
	UFSHCD_CAP_CRYPTO				= 1 << 8,

	/*
	 * This capability allows the controller regulators to be put into
	 * lpm mode aggressively during clock gating.
	 * This would increase power savings.
	 */
	UFSHCD_CAP_AGGR_POWER_COLLAPSE			= 1 << 9,
};
};


struct ufs_hba_variant_params {
struct ufs_hba_variant_params {
@@ -829,6 +836,12 @@ return true;
#endif
#endif
}
}


static inline bool ufshcd_can_aggressive_pc(struct ufs_hba *hba)
{
	return !!(ufshcd_is_link_hibern8(hba) &&
		  (hba->caps & UFSHCD_CAP_AGGR_POWER_COLLAPSE));
}

static inline bool ufshcd_is_auto_hibern8_supported(struct ufs_hba *hba)
static inline bool ufshcd_is_auto_hibern8_supported(struct ufs_hba *hba)
{
{
	return (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT) &&
	return (hba->capabilities & MASK_AUTO_HIBERN8_SUPPORT) &&