1 /* SPDX-License-Identifier: GPL-2.0 */
3 * Universal Flash Storage Host Performance Booster
5 * Copyright (C) 2017-2021 Samsung Electronics Co., Ltd.
8 * Yongmyung Lee <ymhungry.lee@samsung.com>
9 * Jinyoung Choi <j-young.choi@samsung.com>
15 /* hpb response UPIU macro */
16 #define HPB_RSP_NONE 0x0
17 #define HPB_RSP_REQ_REGION_UPDATE 0x1
18 #define HPB_RSP_DEV_RESET 0x2
19 #define MAX_ACTIVE_NUM 2
20 #define MAX_INACTIVE_NUM 2
21 #define DEV_DATA_SEG_LEN 0x14
22 #define DEV_SENSE_SEG_LEN 0x12
23 #define DEV_DES_TYPE 0x80
24 #define DEV_ADDITIONAL_LEN 0x10
26 /* hpb map & entries macro */
27 #define HPB_RGN_SIZE_UNIT 512
28 #define HPB_ENTRY_BLOCK_SIZE 4096
29 #define HPB_ENTRY_SIZE 0x8
30 #define PINNED_NOT_SET U32_MAX
32 /* hpb support chunk size */
33 #define HPB_LEGACY_CHUNK_HIGH 1
34 #define HPB_MULTI_CHUNK_HIGH 255
36 /* hpb vender defined opcode */
37 #define UFSHPB_READ 0xF8
38 #define UFSHPB_READ_BUFFER 0xF9
39 #define UFSHPB_READ_BUFFER_ID 0x01
40 #define UFSHPB_WRITE_BUFFER 0xFA
41 #define UFSHPB_WRITE_BUFFER_INACT_SINGLE_ID 0x01
42 #define UFSHPB_WRITE_BUFFER_PREFETCH_ID 0x02
43 #define UFSHPB_WRITE_BUFFER_INACT_ALL_ID 0x03
44 #define HPB_WRITE_BUFFER_CMD_LENGTH 10
45 #define MAX_HPB_READ_ID 0x7F
46 #define HPB_READ_BUFFER_CMD_LENGTH 10
47 #define LU_ENABLED_HPB_FUNC 0x02
49 #define HPB_RESET_REQ_RETRIES 10
50 #define HPB_MAP_REQ_RETRIES 5
51 #define HPB_REQUEUE_TIME_MS 0
53 #define HPB_SUPPORT_VERSION 0x200
54 #define HPB_SUPPORT_LEGACY_VERSION 0x100
72 /* pinned regions are always active */
84 * struct ufshpb_lu_info - UFSHPB logical unit related info
85 * @num_blocks: the number of logical block
86 * @pinned_start: the start region number of pinned region
87 * @num_pinned: the number of pinned regions
88 * @max_active_rgns: maximum number of active regions
90 struct ufshpb_lu_info {
97 struct ufshpb_map_ctx {
99 unsigned long *ppn_dirty;
102 struct ufshpb_subregion {
103 struct ufshpb_map_ctx *mctx;
104 enum HPB_SRGN_STATE srgn_state;
109 /* subregion reads - for host mode */
112 /* below information is used by rsp_list */
113 struct list_head list_act_srgn;
116 struct ufshpb_region {
117 struct ufshpb_lu *hpb;
118 struct ufshpb_subregion *srgn_tbl;
119 enum HPB_RGN_STATE rgn_state;
123 /* below information is used by rsp_list */
124 struct list_head list_inact_rgn;
126 /* below information is used by lru */
127 struct list_head list_lru_rgn;
128 unsigned long rgn_flags;
129 #define RGN_FLAG_DIRTY 0
130 #define RGN_FLAG_UPDATE 1
132 /* region reads - for host mode */
135 /* region "cold" timer - for host mode */
136 ktime_t read_timeout;
137 unsigned int read_timeout_expiries;
138 struct list_head list_expired_rgn;
141 #define for_each_sub_region(rgn, i, srgn) \
143 ((i) < (rgn)->srgn_cnt) && ((srgn) = &(rgn)->srgn_tbl[i]); \
147 * struct ufshpb_req - HPB related request structure (write/read buffer)
148 * @req: block layer request structure
149 * @bio: bio for this request
150 * @hpb: ufshpb_lu structure that related to
151 * @list_req: ufshpb_req mempool list
152 * @sense: store its sense data
153 * @mctx: L2P map information
154 * @rgn_idx: target region index
155 * @srgn_idx: target sub-region index
156 * @lun: target logical unit number
157 * @m_page: L2P map information data for pre-request
158 * @len: length of host-side cached L2P map in m_page
159 * @lpn: start LPN of L2P map in m_page
164 struct ufshpb_lu *hpb;
165 struct list_head list_req;
168 struct ufshpb_map_ctx *mctx;
169 unsigned int rgn_idx;
170 unsigned int srgn_idx;
181 struct victim_select_info {
182 struct list_head lh_lru_rgn; /* LRU list of regions */
183 int max_lru_active_cnt; /* supported hpb #region - pinned #region */
188 * ufshpb_params - ufs hpb parameters
189 * @requeue_timeout_ms - requeue threshold of wb command (0x2)
190 * @activation_thld - min reads [IOs] to activate/update a region
191 * @normalization_factor - shift right the region's reads
192 * @eviction_thld_enter - min reads [IOs] for the entering region in eviction
193 * @eviction_thld_exit - max reads [IOs] for the exiting region in eviction
194 * @read_timeout_ms - timeout [ms] from the last read IO to the region
195 * @read_timeout_expiries - amount of allowable timeout expireis
196 * @timeout_polling_interval_ms - frequency in which timeouts are checked
197 * @inflight_map_req - number of inflight map requests
199 struct ufshpb_params {
200 unsigned int requeue_timeout_ms;
201 unsigned int activation_thld;
202 unsigned int normalization_factor;
203 unsigned int eviction_thld_enter;
204 unsigned int eviction_thld_exit;
205 unsigned int read_timeout_ms;
206 unsigned int read_timeout_expiries;
207 unsigned int timeout_polling_interval_ms;
208 unsigned int inflight_map_req;
211 struct ufshpb_stats {
224 struct scsi_device *sdev_ufs_lu;
226 spinlock_t rgn_state_lock; /* for protect rgn/srgn state */
227 struct ufshpb_region *rgn_tbl;
231 spinlock_t rsp_list_lock;
232 struct list_head lh_act_srgn; /* hold rsp_list_lock */
233 struct list_head lh_inact_rgn; /* hold rsp_list_lock */
235 /* pre request information */
236 struct ufshpb_req *pre_req;
237 int num_inflight_pre_req;
238 int throttle_pre_req;
239 int num_inflight_map_req; /* hold param_lock */
240 spinlock_t param_lock;
242 struct list_head lh_pre_req_free;
243 int pre_req_max_tr_len;
245 /* cached L2P map management worker */
246 struct work_struct map_work;
248 /* for selecting victim */
249 struct victim_select_info lru_info;
250 struct work_struct ufshpb_normalization_work;
251 struct delayed_work ufshpb_read_to_work;
252 unsigned long work_data_bits;
253 #define TIMEOUT_WORK_RUNNING 0
255 /* pinned region information */
259 /* HPB related configuration */
262 u32 last_srgn_entries;
265 u32 entries_per_rgn_mask;
266 u32 entries_per_rgn_shift;
267 u32 entries_per_srgn;
268 u32 entries_per_srgn_mask;
269 u32 entries_per_srgn_shift;
274 struct ufshpb_stats stats;
275 struct ufshpb_params params;
277 struct kmem_cache *map_req_cache;
278 struct kmem_cache *m_page_cache;
280 struct list_head list_hpb_lu;
286 #ifndef CONFIG_SCSI_UFS_HPB
287 static int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { return 0; }
288 static void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {}
289 static void ufshpb_resume(struct ufs_hba *hba) {}
290 static void ufshpb_suspend(struct ufs_hba *hba) {}
291 static void ufshpb_reset(struct ufs_hba *hba) {}
292 static void ufshpb_reset_host(struct ufs_hba *hba) {}
293 static void ufshpb_init(struct ufs_hba *hba) {}
294 static void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) {}
295 static void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) {}
296 static void ufshpb_remove(struct ufs_hba *hba) {}
297 static bool ufshpb_is_allowed(struct ufs_hba *hba) { return false; }
298 static void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) {}
299 static void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) {}
300 static bool ufshpb_is_legacy(struct ufs_hba *hba) { return false; }
302 int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp);
303 void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp);
304 void ufshpb_resume(struct ufs_hba *hba);
305 void ufshpb_suspend(struct ufs_hba *hba);
306 void ufshpb_reset(struct ufs_hba *hba);
307 void ufshpb_reset_host(struct ufs_hba *hba);
308 void ufshpb_init(struct ufs_hba *hba);
309 void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev);
310 void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev);
311 void ufshpb_remove(struct ufs_hba *hba);
312 bool ufshpb_is_allowed(struct ufs_hba *hba);
313 void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf);
314 void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf);
315 bool ufshpb_is_legacy(struct ufs_hba *hba);
316 extern struct attribute_group ufs_sysfs_hpb_stat_group;
317 extern struct attribute_group ufs_sysfs_hpb_param_group;
320 #endif /* End of Header */