1
2
3
4
5
6
7
8
9
10
11
12#ifndef _UFSHPB_H_
13#define _UFSHPB_H_
14
15
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
25
26
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
31
32
33#define HPB_LEGACY_CHUNK_HIGH 1
34#define HPB_MULTI_CHUNK_LOW 7
35#define HPB_MULTI_CHUNK_HIGH 255
36
37
38#define UFSHPB_READ 0xF8
39#define UFSHPB_READ_BUFFER 0xF9
40#define UFSHPB_READ_BUFFER_ID 0x01
41#define UFSHPB_WRITE_BUFFER 0xFA
42#define UFSHPB_WRITE_BUFFER_INACT_SINGLE_ID 0x01
43#define UFSHPB_WRITE_BUFFER_PREFETCH_ID 0x02
44#define UFSHPB_WRITE_BUFFER_INACT_ALL_ID 0x03
45#define HPB_WRITE_BUFFER_CMD_LENGTH 10
46#define MAX_HPB_READ_ID 0x7F
47#define HPB_READ_BUFFER_CMD_LENGTH 10
48#define LU_ENABLED_HPB_FUNC 0x02
49
50#define HPB_RESET_REQ_RETRIES 10
51#define HPB_MAP_REQ_RETRIES 5
52#define HPB_REQUEUE_TIME_MS 0
53
54#define HPB_SUPPORT_VERSION 0x200
55#define HPB_SUPPORT_LEGACY_VERSION 0x100
56
57enum UFSHPB_MODE {
58 HPB_HOST_CONTROL,
59 HPB_DEVICE_CONTROL,
60};
61
62enum UFSHPB_STATE {
63 HPB_INIT = 0,
64 HPB_PRESENT = 1,
65 HPB_SUSPEND,
66 HPB_FAILED,
67 HPB_RESET,
68};
69
70enum HPB_RGN_STATE {
71 HPB_RGN_INACTIVE,
72 HPB_RGN_ACTIVE,
73
74 HPB_RGN_PINNED,
75};
76
77enum HPB_SRGN_STATE {
78 HPB_SRGN_UNUSED,
79 HPB_SRGN_INVALID,
80 HPB_SRGN_VALID,
81 HPB_SRGN_ISSUED,
82};
83
84
85
86
87
88
89
90
91struct ufshpb_lu_info {
92 int num_blocks;
93 int pinned_start;
94 int num_pinned;
95 int max_active_rgns;
96};
97
98struct ufshpb_map_ctx {
99 struct page **m_page;
100 unsigned long *ppn_dirty;
101};
102
103struct ufshpb_subregion {
104 struct ufshpb_map_ctx *mctx;
105 enum HPB_SRGN_STATE srgn_state;
106 int rgn_idx;
107 int srgn_idx;
108 bool is_last;
109
110
111 unsigned int reads;
112
113
114 struct list_head list_act_srgn;
115};
116
117struct ufshpb_region {
118 struct ufshpb_lu *hpb;
119 struct ufshpb_subregion *srgn_tbl;
120 enum HPB_RGN_STATE rgn_state;
121 int rgn_idx;
122 int srgn_cnt;
123
124
125 struct list_head list_inact_rgn;
126
127
128 struct list_head list_lru_rgn;
129 unsigned long rgn_flags;
130#define RGN_FLAG_DIRTY 0
131#define RGN_FLAG_UPDATE 1
132
133
134 spinlock_t rgn_lock;
135 unsigned int reads;
136
137 ktime_t read_timeout;
138 unsigned int read_timeout_expiries;
139 struct list_head list_expired_rgn;
140};
141
142#define for_each_sub_region(rgn, i, srgn) \
143 for ((i) = 0; \
144 ((i) < (rgn)->srgn_cnt) && ((srgn) = &(rgn)->srgn_tbl[i]); \
145 (i)++)
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162struct ufshpb_req {
163 struct request *req;
164 struct bio *bio;
165 struct ufshpb_lu *hpb;
166 struct list_head list_req;
167 union {
168 struct {
169 struct ufshpb_map_ctx *mctx;
170 unsigned int rgn_idx;
171 unsigned int srgn_idx;
172 unsigned int lun;
173 } rb;
174 struct {
175 struct page *m_page;
176 unsigned int len;
177 unsigned long lpn;
178 } wb;
179 };
180};
181
182struct victim_select_info {
183 struct list_head lh_lru_rgn;
184 int max_lru_active_cnt;
185 atomic_t active_cnt;
186};
187
188
189
190
191
192
193
194
195
196
197
198
199
200struct ufshpb_params {
201 unsigned int requeue_timeout_ms;
202 unsigned int activation_thld;
203 unsigned int normalization_factor;
204 unsigned int eviction_thld_enter;
205 unsigned int eviction_thld_exit;
206 unsigned int read_timeout_ms;
207 unsigned int read_timeout_expiries;
208 unsigned int timeout_polling_interval_ms;
209 unsigned int inflight_map_req;
210};
211
212struct ufshpb_stats {
213 u64 hit_cnt;
214 u64 miss_cnt;
215 u64 rb_noti_cnt;
216 u64 rb_active_cnt;
217 u64 rb_inactive_cnt;
218 u64 map_req_cnt;
219 u64 pre_req_cnt;
220 u64 umap_req_cnt;
221};
222
223struct ufshpb_lu {
224 int lun;
225 struct scsi_device *sdev_ufs_lu;
226
227 spinlock_t rgn_state_lock;
228 struct ufshpb_region *rgn_tbl;
229
230 atomic_t hpb_state;
231
232 spinlock_t rsp_list_lock;
233 struct list_head lh_act_srgn;
234 struct list_head lh_inact_rgn;
235
236
237 struct ufshpb_req *pre_req;
238 int num_inflight_pre_req;
239 int throttle_pre_req;
240 int num_inflight_map_req;
241 spinlock_t param_lock;
242
243 struct list_head lh_pre_req_free;
244 int pre_req_max_tr_len;
245
246
247 struct work_struct map_work;
248
249
250 struct victim_select_info lru_info;
251 struct work_struct ufshpb_normalization_work;
252 struct delayed_work ufshpb_read_to_work;
253 unsigned long work_data_bits;
254#define TIMEOUT_WORK_RUNNING 0
255
256
257 u32 lu_pinned_start;
258 u32 lu_pinned_end;
259
260
261 u32 rgns_per_lu;
262 u32 srgns_per_lu;
263 u32 last_srgn_entries;
264 int srgns_per_rgn;
265 u32 srgn_mem_size;
266 u32 entries_per_rgn_mask;
267 u32 entries_per_rgn_shift;
268 u32 entries_per_srgn;
269 u32 entries_per_srgn_mask;
270 u32 entries_per_srgn_shift;
271 u32 pages_per_srgn;
272
273 bool is_hcm;
274
275 struct ufshpb_stats stats;
276 struct ufshpb_params params;
277
278 struct kmem_cache *map_req_cache;
279 struct kmem_cache *m_page_cache;
280
281 struct list_head list_hpb_lu;
282};
283
284struct ufs_hba;
285struct ufshcd_lrb;
286
287#ifndef CONFIG_SCSI_UFS_HPB
288static int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) { return 0; }
289static void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp) {}
290static void ufshpb_resume(struct ufs_hba *hba) {}
291static void ufshpb_suspend(struct ufs_hba *hba) {}
292static void ufshpb_reset(struct ufs_hba *hba) {}
293static void ufshpb_reset_host(struct ufs_hba *hba) {}
294static void ufshpb_init(struct ufs_hba *hba) {}
295static void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev) {}
296static void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev) {}
297static void ufshpb_remove(struct ufs_hba *hba) {}
298static bool ufshpb_is_allowed(struct ufs_hba *hba) { return false; }
299static void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf) {}
300static void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf) {}
301static bool ufshpb_is_legacy(struct ufs_hba *hba) { return false; }
302#else
303int ufshpb_prep(struct ufs_hba *hba, struct ufshcd_lrb *lrbp);
304void ufshpb_rsp_upiu(struct ufs_hba *hba, struct ufshcd_lrb *lrbp);
305void ufshpb_resume(struct ufs_hba *hba);
306void ufshpb_suspend(struct ufs_hba *hba);
307void ufshpb_reset(struct ufs_hba *hba);
308void ufshpb_reset_host(struct ufs_hba *hba);
309void ufshpb_init(struct ufs_hba *hba);
310void ufshpb_init_hpb_lu(struct ufs_hba *hba, struct scsi_device *sdev);
311void ufshpb_destroy_lu(struct ufs_hba *hba, struct scsi_device *sdev);
312void ufshpb_remove(struct ufs_hba *hba);
313bool ufshpb_is_allowed(struct ufs_hba *hba);
314void ufshpb_get_geo_info(struct ufs_hba *hba, u8 *geo_buf);
315void ufshpb_get_dev_info(struct ufs_hba *hba, u8 *desc_buf);
316bool ufshpb_is_legacy(struct ufs_hba *hba);
317extern struct attribute_group ufs_sysfs_hpb_stat_group;
318extern struct attribute_group ufs_sysfs_hpb_param_group;
319#endif
320
321#endif
322