summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorVenkat Gopalakrishnan <venkatg@codeaurora.org>2016-04-15 11:43:24 -0700
committerKyle Yan <kyan@codeaurora.org>2016-06-08 15:13:42 -0700
commite1fcf7ef3dd94c129aaa4076c477b6a49abc7f32 (patch)
tree2bb634120912ba066d48ed6209c4686619186803
parent6b266ad4c87c7bfe02eb0482191af1bc4c46c7cd (diff)
scsi: ufs: add new get_scale_down_gear vops
Each ufs controller variant can work with various gear speeds that can be supported at a low voltage corner. Add an ops function to query the gear supported to scale down. Also make the hibern8 entry/exit function non static as the variant drivers might need to call hibern8 entry/exit when scaling down to a lower gear. Change-Id: I50008a892c8c21a4a3361998d76a2f8cbc2995bb Signed-off-by: Venkat Gopalakrishnan <venkatg@codeaurora.org>
-rw-r--r--drivers/scsi/ufs/ufshcd.c16
-rw-r--r--drivers/scsi/ufs/ufshcd.h13
2 files changed, 20 insertions, 9 deletions
diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
index 607ed45742c4..54689aa4139f 100644
--- a/drivers/scsi/ufs/ufshcd.c
+++ b/drivers/scsi/ufs/ufshcd.c
@@ -362,8 +362,6 @@ static int ufshcd_disable_clocks(struct ufs_hba *hba,
static int ufshcd_disable_clocks_skip_ref_clk(struct ufs_hba *hba,
bool is_gating_context);
static int ufshcd_set_vccq_rail_unused(struct ufs_hba *hba, bool unused);
-static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba);
-static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba);
static inline void ufshcd_add_delay_before_dme_cmd(struct ufs_hba *hba);
static inline void ufshcd_save_tstamp_of_last_dme_cmd(struct ufs_hba *hba);
static int ufshcd_host_reset_and_restore(struct ufs_hba *hba);
@@ -4019,7 +4017,7 @@ static int __ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
return ret;
}
-static int ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
+int ufshcd_uic_hibern8_enter(struct ufs_hba *hba)
{
int ret = 0, retries;
@@ -4032,7 +4030,7 @@ out:
return ret;
}
-static int ufshcd_uic_hibern8_exit(struct ufs_hba *hba)
+int ufshcd_uic_hibern8_exit(struct ufs_hba *hba)
{
struct uic_command uic_cmd = {0};
int ret;
@@ -8573,9 +8571,9 @@ static bool ufshcd_is_devfreq_scaling_required(struct ufs_hba *hba,
*/
static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up)
{
- #define UFS_MIN_GEAR_TO_SCALE_DOWN UFS_HS_G2
int ret = 0;
struct ufs_pa_layer_attr new_pwr_info;
+ u32 scale_down_gear = ufshcd_vops_get_scale_down_gear(hba);
BUG_ON(!hba->clk_scaling.saved_pwr_info.is_valid);
@@ -8586,16 +8584,16 @@ static int ufshcd_scale_gear(struct ufs_hba *hba, bool scale_up)
memcpy(&new_pwr_info, &hba->pwr_info,
sizeof(struct ufs_pa_layer_attr));
- if (hba->pwr_info.gear_tx > UFS_MIN_GEAR_TO_SCALE_DOWN
- || hba->pwr_info.gear_rx > UFS_MIN_GEAR_TO_SCALE_DOWN) {
+ if (hba->pwr_info.gear_tx > scale_down_gear
+ || hba->pwr_info.gear_rx > scale_down_gear) {
/* save the current power mode */
memcpy(&hba->clk_scaling.saved_pwr_info.info,
&hba->pwr_info,
sizeof(struct ufs_pa_layer_attr));
/* scale down gear */
- new_pwr_info.gear_tx = UFS_MIN_GEAR_TO_SCALE_DOWN;
- new_pwr_info.gear_rx = UFS_MIN_GEAR_TO_SCALE_DOWN;
+ new_pwr_info.gear_tx = scale_down_gear;
+ new_pwr_info.gear_rx = scale_down_gear;
if (!(hba->dev_quirks & UFS_DEVICE_NO_FASTAUTO)) {
new_pwr_info.pwr_tx = FASTAUTO_MODE;
new_pwr_info.pwr_rx = FASTAUTO_MODE;
diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
index 1e5eb3ddd7c4..84bf9d59ad50 100644
--- a/drivers/scsi/ufs/ufshcd.h
+++ b/drivers/scsi/ufs/ufshcd.h
@@ -307,6 +307,8 @@ struct ufs_pwr_mode_info {
* implementations of resetting the hci
* @dbg_register_dump: used to dump controller debug information
* @update_sec_cfg: called to restore host controller secure configuration
+ * @get_scale_down_gear: called to get the minimum supported gear to
+ * scale down
* @add_debugfs: used to add debugfs entries
* @remove_debugfs: used to remove debugfs entries
*/
@@ -332,6 +334,7 @@ struct ufs_hba_variant_ops {
int (*full_reset)(struct ufs_hba *);
void (*dbg_register_dump)(struct ufs_hba *hba);
int (*update_sec_cfg)(struct ufs_hba *hba, bool restore_sec_cfg);
+ u32 (*get_scale_down_gear)(struct ufs_hba *);
#ifdef CONFIG_DEBUG_FS
void (*add_debugfs)(struct ufs_hba *hba, struct dentry *root);
void (*remove_debugfs)(struct ufs_hba *hba);
@@ -970,6 +973,8 @@ void ufshcd_remove(struct ufs_hba *);
int ufshcd_wait_for_register(struct ufs_hba *hba, u32 reg, u32 mask,
u32 val, unsigned long interval_us,
unsigned long timeout_ms, bool can_sleep);
+int ufshcd_uic_hibern8_enter(struct ufs_hba *hba);
+int ufshcd_uic_hibern8_exit(struct ufs_hba *hba);
/**
* ufshcd_set_variant - set variant specific data to the hba
@@ -1239,6 +1244,14 @@ static inline int ufshcd_vops_update_sec_cfg(struct ufs_hba *hba,
return 0;
}
+static inline u32 ufshcd_vops_get_scale_down_gear(struct ufs_hba *hba)
+{
+ if (hba->var && hba->var->vops && hba->var->vops->get_scale_down_gear)
+ return hba->var->vops->get_scale_down_gear(hba);
+ /* Default to lowest high speed gear */
+ return UFS_HS_G1;
+}
+
#ifdef CONFIG_DEBUG_FS
static inline void ufshcd_vops_add_debugfs(struct ufs_hba *hba,
struct dentry *root)