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