1 /* SPDX-License-Identifier: GPL-2.0-or-later */ 2 3 #ifndef _UFSHCD_PRIV_H_ 4 #define _UFSHCD_PRIV_H_ 5 6 #include <linux/pm_runtime.h> 7 #include <ufs/ufshcd.h> 8 9 static inline bool ufshcd_is_user_access_allowed(struct ufs_hba *hba) 10 { 11 return !hba->shutting_down; 12 } 13 14 void ufshcd_schedule_eh_work(struct ufs_hba *hba); 15 16 static inline bool ufshcd_keep_autobkops_enabled_except_suspend( 17 struct ufs_hba *hba) 18 { 19 return hba->caps & UFSHCD_CAP_KEEP_AUTO_BKOPS_ENABLED_EXCEPT_SUSPEND; 20 } 21 22 static inline u8 ufshcd_wb_get_query_index(struct ufs_hba *hba) 23 { 24 if (hba->dev_info.wb_buffer_type == WB_BUF_MODE_LU_DEDICATED) 25 return hba->dev_info.wb_dedicated_lu; 26 return 0; 27 } 28 29 static inline bool ufshcd_is_wb_buf_flush_allowed(struct ufs_hba *hba) 30 { 31 return ufshcd_is_wb_allowed(hba) && 32 !(hba->quirks & UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL); 33 } 34 35 #ifdef CONFIG_SCSI_UFS_HWMON 36 void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask); 37 void ufs_hwmon_remove(struct ufs_hba *hba); 38 void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask); 39 #else 40 static inline void ufs_hwmon_probe(struct ufs_hba *hba, u8 mask) {} 41 static inline void ufs_hwmon_remove(struct ufs_hba *hba) {} 42 static inline void ufs_hwmon_notify_event(struct ufs_hba *hba, u8 ee_mask) {} 43 #endif 44 45 int ufshcd_query_descriptor_retry(struct ufs_hba *hba, 46 enum query_opcode opcode, 47 enum desc_idn idn, u8 index, 48 u8 selector, 49 u8 *desc_buf, int *buf_len); 50 int ufshcd_read_desc_param(struct ufs_hba *hba, 51 enum desc_idn desc_id, 52 int desc_index, 53 u8 param_offset, 54 u8 *param_read_buf, 55 u8 param_size); 56 int ufshcd_query_attr_retry(struct ufs_hba *hba, enum query_opcode opcode, 57 enum attr_idn idn, u8 index, u8 selector, 58 u32 *attr_val); 59 int ufshcd_query_attr(struct ufs_hba *hba, enum query_opcode opcode, 60 enum attr_idn idn, u8 index, u8 selector, u32 *attr_val); 61 int ufshcd_query_flag(struct ufs_hba *hba, enum query_opcode opcode, 62 enum flag_idn idn, u8 index, bool *flag_res); 63 void ufshcd_auto_hibern8_update(struct ufs_hba *hba, u32 ahit); 64 65 #define SD_ASCII_STD true 66 #define SD_RAW false 67 int ufshcd_read_string_desc(struct ufs_hba *hba, u8 desc_index, 68 u8 **buf, bool ascii); 69 70 int ufshcd_hold(struct ufs_hba *hba, bool async); 71 void ufshcd_release(struct ufs_hba *hba); 72 73 void ufshcd_map_desc_id_to_length(struct ufs_hba *hba, enum desc_idn desc_id, 74 int *desc_length); 75 76 int ufshcd_send_uic_cmd(struct ufs_hba *hba, struct uic_command *uic_cmd); 77 78 int ufshcd_exec_raw_upiu_cmd(struct ufs_hba *hba, 79 struct utp_upiu_req *req_upiu, 80 struct utp_upiu_req *rsp_upiu, 81 int msgcode, 82 u8 *desc_buff, int *buff_len, 83 enum query_opcode desc_op); 84 85 int ufshcd_wb_toggle(struct ufs_hba *hba, bool enable); 86 87 /* Wrapper functions for safely calling variant operations */ 88 static inline const char *ufshcd_get_var_name(struct ufs_hba *hba) 89 { 90 if (hba->vops) 91 return hba->vops->name; 92 return ""; 93 } 94 95 static inline void ufshcd_vops_exit(struct ufs_hba *hba) 96 { 97 if (hba->vops && hba->vops->exit) 98 return hba->vops->exit(hba); 99 } 100 101 static inline u32 ufshcd_vops_get_ufs_hci_version(struct ufs_hba *hba) 102 { 103 if (hba->vops && hba->vops->get_ufs_hci_version) 104 return hba->vops->get_ufs_hci_version(hba); 105 106 return ufshcd_readl(hba, REG_UFS_VERSION); 107 } 108 109 static inline int ufshcd_vops_clk_scale_notify(struct ufs_hba *hba, 110 bool up, enum ufs_notify_change_status status) 111 { 112 if (hba->vops && hba->vops->clk_scale_notify) 113 return hba->vops->clk_scale_notify(hba, up, status); 114 return 0; 115 } 116 117 static inline void ufshcd_vops_event_notify(struct ufs_hba *hba, 118 enum ufs_event_type evt, 119 void *data) 120 { 121 if (hba->vops && hba->vops->event_notify) 122 hba->vops->event_notify(hba, evt, data); 123 } 124 125 static inline int ufshcd_vops_setup_clocks(struct ufs_hba *hba, bool on, 126 enum ufs_notify_change_status status) 127 { 128 if (hba->vops && hba->vops->setup_clocks) 129 return hba->vops->setup_clocks(hba, on, status); 130 return 0; 131 } 132 133 static inline int ufshcd_vops_hce_enable_notify(struct ufs_hba *hba, 134 bool status) 135 { 136 if (hba->vops && hba->vops->hce_enable_notify) 137 return hba->vops->hce_enable_notify(hba, status); 138 139 return 0; 140 } 141 static inline int ufshcd_vops_link_startup_notify(struct ufs_hba *hba, 142 bool status) 143 { 144 if (hba->vops && hba->vops->link_startup_notify) 145 return hba->vops->link_startup_notify(hba, status); 146 147 return 0; 148 } 149 150 static inline int ufshcd_vops_pwr_change_notify(struct ufs_hba *hba, 151 enum ufs_notify_change_status status, 152 struct ufs_pa_layer_attr *dev_max_params, 153 struct ufs_pa_layer_attr *dev_req_params) 154 { 155 if (hba->vops && hba->vops->pwr_change_notify) 156 return hba->vops->pwr_change_notify(hba, status, 157 dev_max_params, dev_req_params); 158 159 return -ENOTSUPP; 160 } 161 162 static inline void ufshcd_vops_setup_task_mgmt(struct ufs_hba *hba, 163 int tag, u8 tm_function) 164 { 165 if (hba->vops && hba->vops->setup_task_mgmt) 166 return hba->vops->setup_task_mgmt(hba, tag, tm_function); 167 } 168 169 static inline void ufshcd_vops_hibern8_notify(struct ufs_hba *hba, 170 enum uic_cmd_dme cmd, 171 enum ufs_notify_change_status status) 172 { 173 if (hba->vops && hba->vops->hibern8_notify) 174 return hba->vops->hibern8_notify(hba, cmd, status); 175 } 176 177 static inline int ufshcd_vops_apply_dev_quirks(struct ufs_hba *hba) 178 { 179 if (hba->vops && hba->vops->apply_dev_quirks) 180 return hba->vops->apply_dev_quirks(hba); 181 return 0; 182 } 183 184 static inline void ufshcd_vops_fixup_dev_quirks(struct ufs_hba *hba) 185 { 186 if (hba->vops && hba->vops->fixup_dev_quirks) 187 hba->vops->fixup_dev_quirks(hba); 188 } 189 190 static inline int ufshcd_vops_suspend(struct ufs_hba *hba, enum ufs_pm_op op, 191 enum ufs_notify_change_status status) 192 { 193 if (hba->vops && hba->vops->suspend) 194 return hba->vops->suspend(hba, op, status); 195 196 return 0; 197 } 198 199 static inline int ufshcd_vops_resume(struct ufs_hba *hba, enum ufs_pm_op op) 200 { 201 if (hba->vops && hba->vops->resume) 202 return hba->vops->resume(hba, op); 203 204 return 0; 205 } 206 207 static inline void ufshcd_vops_dbg_register_dump(struct ufs_hba *hba) 208 { 209 if (hba->vops && hba->vops->dbg_register_dump) 210 hba->vops->dbg_register_dump(hba); 211 } 212 213 static inline int ufshcd_vops_device_reset(struct ufs_hba *hba) 214 { 215 if (hba->vops && hba->vops->device_reset) 216 return hba->vops->device_reset(hba); 217 218 return -EOPNOTSUPP; 219 } 220 221 static inline void ufshcd_vops_config_scaling_param(struct ufs_hba *hba, 222 struct devfreq_dev_profile *p, 223 struct devfreq_simple_ondemand_data *data) 224 { 225 if (hba->vops && hba->vops->config_scaling_param) 226 hba->vops->config_scaling_param(hba, p, data); 227 } 228 229 extern const struct ufs_pm_lvl_states ufs_pm_lvl_states[]; 230 231 /** 232 * ufshcd_scsi_to_upiu_lun - maps scsi LUN to UPIU LUN 233 * @scsi_lun: scsi LUN id 234 * 235 * Returns UPIU LUN id 236 */ 237 static inline u8 ufshcd_scsi_to_upiu_lun(unsigned int scsi_lun) 238 { 239 if (scsi_is_wlun(scsi_lun)) 240 return (scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID) 241 | UFS_UPIU_WLUN_ID; 242 else 243 return scsi_lun & UFS_UPIU_MAX_UNIT_NUM_ID; 244 } 245 246 int __ufshcd_write_ee_control(struct ufs_hba *hba, u32 ee_ctrl_mask); 247 int ufshcd_write_ee_control(struct ufs_hba *hba); 248 int ufshcd_update_ee_control(struct ufs_hba *hba, u16 *mask, 249 const u16 *other_mask, u16 set, u16 clr); 250 251 static inline int ufshcd_update_ee_drv_mask(struct ufs_hba *hba, 252 u16 set, u16 clr) 253 { 254 return ufshcd_update_ee_control(hba, &hba->ee_drv_mask, 255 &hba->ee_usr_mask, set, clr); 256 } 257 258 static inline int ufshcd_update_ee_usr_mask(struct ufs_hba *hba, 259 u16 set, u16 clr) 260 { 261 return ufshcd_update_ee_control(hba, &hba->ee_usr_mask, 262 &hba->ee_drv_mask, set, clr); 263 } 264 265 static inline int ufshcd_rpm_get_sync(struct ufs_hba *hba) 266 { 267 return pm_runtime_get_sync(&hba->ufs_device_wlun->sdev_gendev); 268 } 269 270 static inline int ufshcd_rpm_put_sync(struct ufs_hba *hba) 271 { 272 return pm_runtime_put_sync(&hba->ufs_device_wlun->sdev_gendev); 273 } 274 275 static inline void ufshcd_rpm_get_noresume(struct ufs_hba *hba) 276 { 277 pm_runtime_get_noresume(&hba->ufs_device_wlun->sdev_gendev); 278 } 279 280 static inline int ufshcd_rpm_resume(struct ufs_hba *hba) 281 { 282 return pm_runtime_resume(&hba->ufs_device_wlun->sdev_gendev); 283 } 284 285 static inline int ufshcd_rpm_put(struct ufs_hba *hba) 286 { 287 return pm_runtime_put(&hba->ufs_device_wlun->sdev_gendev); 288 } 289 290 /** 291 * ufs_is_valid_unit_desc_lun - checks if the given LUN has a unit descriptor 292 * @dev_info: pointer of instance of struct ufs_dev_info 293 * @lun: LU number to check 294 * @return: true if the lun has a matching unit descriptor, false otherwise 295 */ 296 static inline bool ufs_is_valid_unit_desc_lun(struct ufs_dev_info *dev_info, 297 u8 lun, u8 param_offset) 298 { 299 if (!dev_info || !dev_info->max_lu_supported) { 300 pr_err("Max General LU supported by UFS isn't initialized\n"); 301 return false; 302 } 303 /* WB is available only for the logical unit from 0 to 7 */ 304 if (param_offset == UNIT_DESC_PARAM_WB_BUF_ALLOC_UNITS) 305 return lun < UFS_UPIU_MAX_WB_LUN_ID; 306 return lun == UFS_UPIU_RPMB_WLUN || (lun < dev_info->max_lu_supported); 307 } 308 309 #endif /* _UFSHCD_PRIV_H_ */ 310