1 // SPDX-License-Identifier: GPL-2.0+
2 /*
3 * Rockchip UFS Host Controller driver
4 *
5 * Copyright (C) 2024 Rockchip Electronics Co.Ltd.
6 */
7
8 #include <charset.h>
9 #include <common.h>
10 #include <dm.h>
11 #include <log.h>
12 #include <dm/lists.h>
13 #include <dm/device-internal.h>
14 #include <malloc.h>
15 #include <hexdump.h>
16 #include <scsi.h>
17 #include <asm/io.h>
18 #include <asm/dma-mapping.h>
19 #include <linux/bitops.h>
20 #include <linux/delay.h>
21
22 #include "ufs-rockchip-usbplug.h"
23 #include "ufs.h"
24 /* Query request retries */
25 #define QUERY_REQ_RETRIES 3
26 /* Query request timeout */
27 #define QUERY_REQ_TIMEOUT 1500 /* 1.5 seconds */
28
29 #if defined(CONFIG_SUPPORT_USBPLUG)
30 int _ufs_start(struct ufs_hba *hba);
31
ufs_info_show_dev_desc(void * buf)32 static void ufs_info_show_dev_desc(void *buf)
33 {
34 struct ufs_device_descriptor *dev = (struct ufs_device_descriptor *)buf;
35
36 printf("---------------------------\n");
37 printf("---UFS Device Descriptor---\n");
38 printf("---------------------------\n");
39 printf("bLength: 0x%x\n", dev->b_length);
40 printf("bDescriptorIDN: 0x%x\n", dev->b_descriptor_idn);
41 printf("bDevice: 0x%x\n", dev->b_device);
42 printf("bDeviceClass: 0x%x\n", dev->b_device_class);
43 printf("bDeviceSubClass: 0x%x\n", dev->b_device_sub_class);
44 printf("bProtocol: 0x%x\n", dev->b_protocol);
45 printf("bNumberLU: 0x%x\n", dev->b_number_lu);
46 printf("bNumberWLU: 0x%x\n", dev->b_number_wlu);
47 printf("bBootEnable: 0x%x\n", dev->b_boot_enable);
48 printf("bDescrAccessEn: 0x%x\n", dev->b_descr_access_en);
49 printf("bInitPowerMode: 0x%x\n", dev->b_init_power_mode);
50 printf("bHighPriorityLUN: 0x%x\n", dev->b_high_priority_lun);
51 printf("bSecureRemovalType: 0x%x\n", dev->b_secure_removal_type);
52 printf("bSecurityLU: 0x%x\n", dev->b_security_lu);
53 printf("bBackgroundOpsTermLat: 0x%x\n", dev->b_background_ops_term_lat);
54 printf("bInitActiveICCLevel: 0x%x\n", dev->b_init_active_icc_level);
55 printf("wSpecVersion: 0x%x\n", to_bigendian16(dev->w_spec_version));
56 printf("wManufactureDate: 0x%x\n", to_bigendian16(dev->w_manufacture_date));
57 printf("iManufacturerName: 0x%x\n", dev->i_manufacturer_name);
58 printf("iProductName: 0x%x\n", dev->i_product_name);
59 printf("iSerialNumber: 0x%x\n", dev->i_serial_number);
60 printf("iOemID: 0x%x\n", dev->i_oem_id);
61 printf("wManufacturerID: 0x%x\n", to_bigendian16(dev->w_manufacturer_id));
62 printf("bUD0BaseOffset: 0x%x\n", dev->b_ud_0base_offset);
63 printf("bUDConfigPLength: 0x%x\n", dev->b_ud_config_plength);
64 printf("bDeviceRTTCap: 0x%x\n", dev->b_device_rtt_cap);
65 printf("wPeriodicRTCUpdate: 0x%x\n", to_bigendian16(dev->w_periodic_rtc_update));
66 printf("bUFSFeatureSupport: 0x%x\n", dev->b_ufs_feature_support);
67 printf("bFFUTimeout: 0x%x\n", dev->b_ffu_timeout);
68 printf("bQueueDepth: 0x%x\n", dev->b_queue_depth);
69 printf("wDeviceVersion: 0x%x\n", to_bigendian16(dev->w_device_version));
70 printf("bNumSecureWPArea: 0x%x\n", dev->b_num_secure_wp_area);
71 printf("dPSAMaxDataSize: 0x%x\n", to_bigendian32(dev->d_psa_max_data_size));
72 printf("bPSAStateTimeout: 0x%x\n", dev->b_psa_state_timeout);
73 printf("iProductRevisionLevel: 0x%x\n", dev->i_product_revision_level);
74 }
75
ufs_info_show_conf_desc(void * buf)76 static void ufs_info_show_conf_desc(void *buf)
77 {
78 struct ufs_configuration_descriptor *c_desc = (struct ufs_configuration_descriptor *)buf;
79 struct ufs_dev_desc_configuration_param *dev;
80 struct ufs_unit_desc_configuration_param *unit;
81 int i;
82
83 dev = &c_desc->dev_desc_conf_param;
84 printf("----------------------------------------\n");
85 printf("---UFS Device Descriptor Config Param---\n");
86 printf("----------------------------------------\n");
87 printf("bLength: 0x%x\n", dev->b_length);
88 printf("bDescriptorIDN: 0x%x\n", dev->b_descriptor_idn);
89 printf("bConfDescContinue: 0x%x\n", dev->b_conf_desc_continue);
90 printf("bBootEnable: 0x%x\n", dev->b_boot_enable);
91 printf("bDescrAccessEn: 0x%x\n", dev->b_descr_access_en);
92 printf("bInitPowerMode: 0x%x\n", dev->b_init_power_mode);
93 printf("bHighPriorityLUN: 0x%x\n", dev->b_high_priority_lun);
94 printf("bSecureRemovalType: 0x%x\n", dev->b_secure_removal_type);
95 printf("bInitActiveICCLevel: 0x%x\n", dev->b_init_active_icc_level);
96 printf("wPeriodicRTCUpdate: 0x%x\n", to_bigendian16(dev->w_periodic_rtc_update));
97 printf("bSecureRemovalType: 0x%x\n", dev->b_secure_removal_type);
98 printf("bInitActiveICCLevel: 0x%x\n", dev->b_init_active_icc_level);
99 printf("wPeriodicRTCUpdate: 0x%x\n", to_bigendian16(dev->w_periodic_rtc_update));
100 printf("bWB_EN: 0x%x\n", dev->b_write_booster_buffer_reserve_user_space_en);
101 printf("WB_TYPE: 0x%x\n", dev->b_write_booster_buffer_type);
102 printf("WB_alloc_units: 0x%x\n", to_bigendian32(dev->d_num_shared_write_booster_buffer_alloc_units));
103
104 for (i = 0; i < UNIT_DESCS_COUNT; i++) {
105 unit = &c_desc->unit_desc_conf_param[i];
106
107 printf("-----------------------------------------\n");
108 printf("---UFS Unit %d Descriptor Config Param---\n", i);
109 printf("-----------------------------------------\n");
110 printf("bLUEnable: 0x%x\n", unit->b_lu_enable);
111 printf("bBootLunID: 0x%x\n", unit->b_boot_lun_id);
112 printf("bLUWriteProtect: 0x%x\n", unit->b_lu_write_protect);
113 printf("bMemoryType: 0x%x\n", unit->b_memory_type);
114 printf("dNumAllocUnits: 0x%x\n", to_bigendian32(unit->d_num_alloc_units));
115 printf("bDataReliability: 0x%x\n", unit->b_data_reliability);
116 printf("bLogicalBlockSize: 0x%x\n", unit->b_logical_block_size);
117 printf("bProvisioningType: 0x%x\n", unit->b_provisioning_type);
118 printf("wContextCapabilities: 0x%x\n", to_bigendian16(unit->w_context_capabilities));
119 }
120 }
121
ufs_get_configuration_desc(struct ufs_hba * hba,struct ufs_configuration_descriptor * c_desc)122 static int ufs_get_configuration_desc(struct ufs_hba *hba, struct ufs_configuration_descriptor *c_desc)
123 {
124 u8 desc_buf[CONFIGURATION_DESC_V31_LENGTH];
125 u8 *buf = desc_buf;
126 int length = hba->desc_size.conf_desc;
127 int err;
128
129 if (CONFIGURATION_DESC_V31_LENGTH == hba->desc_size.conf_desc) {
130 buf = (u8 *)c_desc;
131 } else if(CONFIGURATION_DESC_V22_LENGTH != hba->desc_size.conf_desc &&
132 CONFIGURATION_DESC_V30_LENGTH != hba->desc_size.conf_desc) {
133 return -EINVAL;
134 }
135
136 err = ufshcd_read_desc_param(hba, QUERY_DESC_IDN_CONFIGURATION, 0, 0, buf, length);
137 if (err) {
138 dev_err(hba->dev, "%s: Failed reading configuration Desc. err = %d\n",
139 __func__, err);
140 return err;
141 }
142
143 if (CONFIGURATION_DESC_V22_LENGTH == hba->desc_size.conf_desc) {
144 memcpy(&c_desc->dev_desc_conf_param, buf, 0x10);
145 buf += 0x10;
146 for (int i = 0; i < UNIT_DESCS_COUNT; i++) {
147 memcpy(&c_desc->unit_desc_conf_param[i], buf, 0x10);
148 buf += 0x10;
149 }
150 }
151
152 if (CONFIGURATION_DESC_V30_LENGTH == hba->desc_size.conf_desc) {
153 memcpy(&c_desc->dev_desc_conf_param, buf, 0x12);
154 buf += 0x12;
155 for (int i = 0; i < UNIT_DESCS_COUNT; i++) {
156 memcpy(&c_desc->unit_desc_conf_param[i], buf, 0x1A);
157 buf += 0x1A;
158 }
159 }
160
161 return err;
162 }
163
ufshcd_write_desc_param(struct ufs_hba * hba,enum desc_idn desc_id,int desc_index,u8 param_offset,u8 * param_read_buf,u8 param_size)164 static int ufshcd_write_desc_param(struct ufs_hba *hba, enum desc_idn desc_id,
165 int desc_index, u8 param_offset, u8 *param_read_buf,
166 u8 param_size)
167 {
168 int ret;
169 u8 *desc_buf;
170 int buff_len;
171
172 /* Safety check */
173 if (desc_id >= QUERY_DESC_IDN_MAX || !param_size)
174 return -EINVAL;
175
176 /* Get the max length of descriptor from structure filled up at probe
177 * time.
178 */
179 ret = ufshcd_map_desc_id_to_length(hba, desc_id, &buff_len);
180
181 /* Sanity checks */
182 if (ret || !buff_len) {
183 dev_err(hba->dev, "%s: Failed to get full descriptor length\n",
184 __func__);
185 return ret;
186 }
187
188 desc_buf = param_read_buf;
189 /* Request for full descriptor */
190 ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_WRITE_DESC,
191 desc_id, desc_index, 0, desc_buf,
192 &buff_len);
193
194 if (ret)
195 dev_err(hba->dev, "%s: Failed write descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d\n",
196 __func__, desc_id, desc_index, param_offset, ret);
197
198 return ret;
199 }
200
ufs_write_configuration_desc(struct ufs_hba * hba,struct ufs_configuration_descriptor * c_desc)201 static int ufs_write_configuration_desc(struct ufs_hba *hba, struct ufs_configuration_descriptor *c_desc)
202 {
203 u8 desc_buf[CONFIGURATION_DESC_V31_LENGTH];
204 u8 *buf = desc_buf;
205 int length = hba->desc_size.conf_desc;
206 int err;
207
208 if (CONFIGURATION_DESC_V31_LENGTH == hba->desc_size.conf_desc) {
209 buf = (u8 *)c_desc;
210 } else if (CONFIGURATION_DESC_V22_LENGTH == hba->desc_size.conf_desc) {
211 memcpy(buf, &c_desc->dev_desc_conf_param, 0x10);
212 buf += 0x10;
213 for (int i = 0; i < UNIT_DESCS_COUNT; i++) {
214 memcpy(buf, &c_desc->unit_desc_conf_param[i], 0x10);
215 buf += 0x10;
216 }
217 buf = desc_buf;
218 } else if (CONFIGURATION_DESC_V30_LENGTH == hba->desc_size.conf_desc) {
219 memcpy(buf, &c_desc->dev_desc_conf_param, 0x12);
220 buf += 0x12;
221 for (int i = 0; i < UNIT_DESCS_COUNT; i++) {
222 memcpy(buf, &c_desc->unit_desc_conf_param[i], 0x1A);
223 buf += 0x1A;
224 }
225 buf = desc_buf;
226 } else {
227 return -EINVAL;
228 }
229
230 err = ufshcd_write_desc_param(hba, QUERY_DESC_IDN_CONFIGURATION, 0, 0, buf, length);
231 if (err) {
232 dev_err(hba->dev, "%s: Failed reading configuration Desc. err = %d\n",
233 __func__, err);
234 return err;
235 }
236
237 return err;
238 }
239
ufs_lu_configuration(struct ufs_hba * hba,struct ufs_configuration_descriptor * c_desc)240 static void ufs_lu_configuration(struct ufs_hba *hba, struct ufs_configuration_descriptor *c_desc)
241 {
242 uint32_t denominator = hba->geo_desc->b_allocation_unit_size * to_bigendian32(hba->geo_desc->d_segment_size);
243 struct ufs_dev_desc_configuration_param *dev;
244 struct ufs_unit_desc_configuration_param *unit;
245 uint32_t alloced_units = 0;
246 int i, cap_adj_fac;
247 uint64_t total_raw_device_capacity;
248 uint32_t max_wb_alloc_units = cpu_to_be32(hba->geo_desc->d_write_booster_buffer_max_alloc_units);
249 uint32_t wb_alloc_units;
250
251 cap_adj_fac = to_bigendian16(hba->geo_desc->w_enhanced1_cap_adj_fac) / 256;
252 total_raw_device_capacity = cpu_to_be64(hba->geo_desc->q_total_raw_device_capacity);
253
254 dev = &c_desc->dev_desc_conf_param;
255 dev->b_boot_enable = 0x1;
256 dev->b_descr_access_en = 0x0;
257 dev->b_init_power_mode = 0x1;
258 dev->b_high_priority_lun = 0x7F;
259 dev->b_secure_removal_type = 0x0;
260 dev->b_init_active_icc_level = 0x0;
261 dev->w_periodic_rtc_update = 0x0;
262
263 unit = &c_desc->unit_desc_conf_param[0];
264 /* lu 1: boot lu A 4MB */
265 unit[1].b_boot_lun_id = WELL_BOOT_LU_A; /* lu 0, boot a */
266 unit[1].b_memory_type = 0x3;
267 unit[1].d_num_alloc_units = (4 * 0x800 * cap_adj_fac + denominator - 1) / denominator;
268 alloced_units += unit[1].d_num_alloc_units;
269 /* lu 2: boot lu B 4MB */
270 unit[2].b_boot_lun_id = WELL_BOOT_LU_B; /* lu 1, boot b */
271 unit[2].b_memory_type = 0x3; /* lu 0, Enhanced Memory */
272 unit[2].d_num_alloc_units = (4 * 0x800 * cap_adj_fac + denominator - 1) / denominator;
273 alloced_units += unit[2].d_num_alloc_units;
274 /* lu 3: data lu 8MB */
275 unit[3].b_boot_lun_id = 0x0; /* lu 2 */
276 unit[3].b_memory_type = 0x3; /* lu 2, Enhanced Memory */
277 unit[3].d_num_alloc_units = (8 * 0x800 * cap_adj_fac + denominator - 1) / denominator;
278 alloced_units += unit[3].d_num_alloc_units;
279
280 if (max_wb_alloc_units) {
281 wb_alloc_units = max_wb_alloc_units;
282 if (wb_alloc_units > max_wb_alloc_units)
283 wb_alloc_units = max_wb_alloc_units;
284 dev->b_write_booster_buffer_reserve_user_space_en = 1;
285 dev->b_write_booster_buffer_type = 1;
286 dev->d_num_shared_write_booster_buffer_alloc_units = to_bigendian32(wb_alloc_units);
287 }
288
289 /* lu 0: data lu, max capacity*/
290 unit[0].b_boot_lun_id = 0x0; /* lu 3 */
291 unit[0].b_memory_type = 0x0; /* lu 3, Normal Memory */
292 unit[0].d_num_alloc_units = lower_32_bits(total_raw_device_capacity) / denominator - alloced_units;
293
294 for (i = 0; i <= 3; i++) { /* lu 0 - 3 */
295 unit[i].b_lu_enable = 0x1;
296 unit[i].b_lu_write_protect = 0x0;
297 unit[i].b_data_reliability = 0x1;
298 unit[i].b_logical_block_size = 0x0c;
299 unit[i].b_provisioning_type = 0x2;
300 unit[i].w_context_capabilities = 0x0;
301 unit[i].d_num_alloc_units = to_bigendian32(unit[i].d_num_alloc_units);
302 }
303 }
304
compair_conf_desp(struct ufs_configuration_descriptor * cda,struct ufs_configuration_descriptor * cdb)305 static int compair_conf_desp(struct ufs_configuration_descriptor *cda, struct ufs_configuration_descriptor *cdb)
306 {
307 struct ufs_dev_desc_configuration_param *dev_a, *dev_b;
308 struct ufs_unit_desc_configuration_param *unit_a, *unit_b;
309 int i, ret;
310
311 dev_a = &cda->dev_desc_conf_param;
312 dev_b = &cdb->dev_desc_conf_param;
313
314 if (dev_a->b_boot_enable != dev_b->b_boot_enable)
315 return 0x3;
316 if (dev_a->b_descr_access_en != dev_b->b_descr_access_en)
317 return 0x4;
318 if (dev_a->b_init_power_mode != dev_b->b_init_power_mode)
319 return 0x5;
320 if (dev_a->b_high_priority_lun != dev_b->b_high_priority_lun)
321 return 0x6;
322 if (dev_a->b_secure_removal_type != dev_b->b_secure_removal_type)
323 return 0x7;
324 if (dev_a->b_init_active_icc_level != dev_b->b_init_active_icc_level)
325 return 0x8;
326 if (dev_a->w_periodic_rtc_update != dev_b->w_periodic_rtc_update)
327 return 0x9;
328 if (dev_a->b_write_booster_buffer_reserve_user_space_en !=
329 dev_b->b_write_booster_buffer_reserve_user_space_en)
330 return 0xA;
331 if (dev_a->b_write_booster_buffer_type != dev_b->b_write_booster_buffer_type)
332 return 0xB;
333 if (dev_a->d_num_shared_write_booster_buffer_alloc_units !=
334 dev_b->d_num_shared_write_booster_buffer_alloc_units)
335 return 0xC;
336
337 for (i = 0; i < UNIT_DESCS_COUNT; i++) {
338 unit_a = &cda->unit_desc_conf_param[i];
339 unit_b = &cdb->unit_desc_conf_param[i];
340
341 ret = 0x10 * (i + 1);
342 if (unit_a->b_lu_enable != unit_b->b_lu_enable)
343 return ret;
344 if (unit_a->b_boot_lun_id != unit_b->b_boot_lun_id)
345 return ret + 0x1;
346 if (unit_a->b_lu_write_protect != unit_b->b_lu_write_protect)
347 return ret + 0x2;
348 if (unit_a->b_memory_type != unit_b->b_memory_type)
349 return ret + 0x3;
350 if (unit_a->d_num_alloc_units != unit_b->d_num_alloc_units)
351 return ret + 0x4;
352 if (unit_a->b_data_reliability != unit_b->b_data_reliability)
353 return ret + 0x8;
354 if (unit_a->b_logical_block_size != unit_b->b_logical_block_size)
355 return ret + 0x9;
356 if (unit_a->b_provisioning_type != unit_b->b_provisioning_type)
357 return ret + 0xA;
358 if (unit_a->w_context_capabilities != unit_b->w_context_capabilities)
359 return ret + 0xB;
360 }
361 return 0;
362 }
363
364
365 /**
366 * ufshcd_init_query() - init the query response and request parameters
367 */
ufshcd_init_query(struct ufs_hba * hba,struct ufs_query_req ** request,struct ufs_query_res ** response,enum query_opcode opcode,u8 idn,u8 index,u8 selector)368 static inline void ufshcd_init_query(struct ufs_hba *hba,
369 struct ufs_query_req **request,
370 struct ufs_query_res **response,
371 enum query_opcode opcode,
372 u8 idn, u8 index, u8 selector)
373 {
374 *request = &hba->dev_cmd.query.request;
375 *response = &hba->dev_cmd.query.response;
376 memset(*request, 0, sizeof(struct ufs_query_req));
377 memset(*response, 0, sizeof(struct ufs_query_res));
378 (*request)->upiu_req.opcode = opcode;
379 (*request)->upiu_req.idn = idn;
380 (*request)->upiu_req.index = index;
381 (*request)->upiu_req.selector = selector;
382 }
383
384 /**
385 * ufshcd_query_flag() - API function for sending flag query requests
386 */
ufshcd_query_attribute(struct ufs_hba * hba,enum query_opcode opcode,enum attr_id idn,u8 index,u8 selector,u32 * value)387 static int ufshcd_query_attribute(struct ufs_hba *hba,enum query_opcode opcode,
388 enum attr_id idn, u8 index, u8 selector, u32 *value)
389 {
390 struct ufs_query_req *request = &hba->dev_cmd.query.request;
391 struct ufs_query_res *response = &hba->dev_cmd.query.response;
392 int err;
393 int timeout = QUERY_REQ_TIMEOUT;
394
395 memset(request, 0, sizeof(struct ufs_query_req));
396 memset(response, 0, sizeof(struct ufs_query_res));
397 request->upiu_req.opcode = opcode;
398 request->upiu_req.idn = idn;
399 request->upiu_req.index = 0;
400 request->upiu_req.selector = 0;
401
402 switch (opcode) {
403 case UPIU_QUERY_OPCODE_WRITE_ATTR:
404 request->query_func = UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST;
405 request->upiu_req.value = be32_to_cpu(*value);
406 break;
407 case UPIU_QUERY_OPCODE_READ_ATTR:
408 request->query_func = UPIU_QUERY_FUNC_STANDARD_READ_REQUEST;
409 break;
410 default:
411 dev_err(hba->dev,
412 "%s: Expected query flag opcode but got = %d\n",
413 __func__, opcode);
414 err = -EINVAL;
415 goto out;
416 }
417
418 err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, timeout);
419
420 if (err) {
421 dev_err(hba->dev,
422 "%s: Sending flag query for idn %d failed, err = %d\n",
423 __func__, idn, err);
424 goto out;
425 }
426
427 if (value)
428 *value = be32_to_cpu(response->upiu_res.value);
429
430 out:
431 return err;
432 }
433
ufshcd_query_attribute_retry(struct ufs_hba * hba,enum query_opcode opcode,enum attr_id idn,u8 index,u8 selector,u32 * value)434 static int ufshcd_query_attribute_retry(struct ufs_hba *hba, enum query_opcode opcode,
435 enum attr_id idn, u8 index, u8 selector, u32 *value)
436 {
437 int ret;
438 int retries;
439
440 for (retries = 0; retries < QUERY_REQ_RETRIES; retries++) {
441 ret = ufshcd_query_attribute(hba, opcode, idn, index, selector, value);
442 if (ret)
443 dev_dbg(hba->dev,
444 "%s: failed with error %d, retries %d\n",
445 __func__, ret, retries);
446 else
447 break;
448 }
449
450 if (ret)
451 dev_err(hba->dev,
452 "%s: query attribute, opcode %d, idn %d, failed with error %d after %d retires\n",
453 __func__, opcode, idn, ret, retries);
454 return ret;
455 }
456
read_attribute(struct ufs_hba * hba,enum attr_id idn,u8 index,u8 selector,u32 * value)457 static int read_attribute(struct ufs_hba *hba, enum attr_id idn, u8 index, u8 selector, u32 *value)
458 {
459 int ret;
460
461 ret = ufshcd_query_attribute_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
462 idn, index, 0, value);
463 return ret;
464 }
465
write_attribute(struct ufs_hba * hba,enum attr_id idn,u8 index,u8 selector,u32 * value)466 static int write_attribute(struct ufs_hba *hba, enum attr_id idn, u8 index, u8 selector, u32 *value)
467 {
468 int ret;
469
470 ret = ufshcd_query_attribute_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR,
471 idn, index, 0, value);
472 return ret;
473 }
474
set_boot_lu_enable(struct ufs_hba * hba)475 static int set_boot_lu_enable(struct ufs_hba *hba)
476 {
477 uint32_t value = 0;
478 uint32_t target_value = DEFAULT_BOOT_LUN;
479 int ret;
480
481 ret = read_attribute(hba, B_BOOT_LUNEN, 0, 0, &value);
482 if (ret) {
483 printf("read bBootLunEn fail. ret = %d\n", ret);
484 return ret;
485 }
486
487 if (value != 0)
488 printf("UFS get boot W-LU-%c\n", (value == WELL_BOOT_LU_A) ? 'A' : 'B');
489
490 if (value == target_value)
491 return 0;
492
493 /* set default boot from Boot LU A */
494 value = target_value;
495 ret = write_attribute(hba, B_BOOT_LUNEN, 0, 0, &value);
496 if (ret) {
497 printf("write bBootLunEn attribute fail. ret = %d\n", ret);
498 return ret;
499 }
500
501 ret = read_attribute(hba, B_BOOT_LUNEN, 0, 0, &value);
502 if (ret) {
503 printf("read bBootLunEn fail. ret = %d\n", ret);
504 return ret;
505 }
506
507 if (target_value == value)
508 return 0;
509
510 printf("UFS set boot W-LU(%c) Fail value = %x\n", (value == WELL_BOOT_LU_A) ? 'A' : 'B', value);
511 return 0;
512 }
513
ufs_set_ref_clk(struct ufs_hba * hba)514 static int ufs_set_ref_clk(struct ufs_hba *hba)
515 {
516 uint32_t value;
517 int ret;
518 uint32_t target_ref_clk;
519
520 target_ref_clk = 1; /* 26 MHz */
521
522 ret = read_attribute(hba, B_REFCLK_FREQ, 0, 0, &value);
523 if (ret) {
524 printf("read bRefClkFreq fail. ret = %d\n", ret);
525 return ret;
526 }
527
528 printf("UFS get ref clock %d Mhz\n", (value == 1) ? 26 : 19);
529 if (target_ref_clk == value)
530 return 0;
531
532 /* set default boot from Boot LU A */
533 ret = write_attribute(hba, B_REFCLK_FREQ, 0, 0, &target_ref_clk);
534 if (ret) {
535 printf("write bRefClkFreq attribute fail. ret = %d\n", ret);
536 return ret;
537 }
538
539 ret = read_attribute(hba, B_REFCLK_FREQ, 0, 0, &value);
540 if (ret) {
541 printf("read bRefClkFreq fail. ret = %d\n", ret);
542 return ret;
543 }
544
545 if (target_ref_clk == value)
546 return 0;
547
548 printf("UFS set bRefClkFreq 26Mhz Fail\n");
549 return -EINVAL;
550 }
551
ufs_create_partition_inventory(struct ufs_hba * hba)552 int ufs_create_partition_inventory(struct ufs_hba *hba)
553 {
554 int err, length;
555
556 length = (int)sizeof(struct ufs_geometry_descriptor);
557 if (length > hba->desc_size.geom_desc)
558 length = hba->desc_size.geom_desc;
559 err = ufshcd_read_desc_param(hba, QUERY_DESC_IDN_GEOMETRY, 0, 0, (u8 *)hba->geo_desc, length);
560 if (err) {
561 dev_err(hba->dev, "%s: Failed reading geometry Desc. err = %d\n", __func__, err);
562 return err;
563 }
564
565 dev_err(hba->dev, "%s: WB_max_alloc_units = %x\n", __func__,
566 hba->geo_desc->d_write_booster_buffer_max_alloc_units);
567
568 err = ufs_get_configuration_desc(hba, hba->rc_desc);
569 if (err) {
570 dev_err(hba->dev, "%s: Failed getting conf info. err = %d\n", __func__, err);
571 return err;
572 }
573 ufs_info_show_conf_desc(hba->rc_desc);
574
575 memset(hba->wc_desc, 0, sizeof(struct ufs_configuration_descriptor));
576 hba->wc_desc->dev_desc_conf_param.b_length = hba->rc_desc->dev_desc_conf_param.b_length;
577 hba->wc_desc->dev_desc_conf_param.b_descriptor_idn = hba->rc_desc->dev_desc_conf_param.b_descriptor_idn;
578 ufs_lu_configuration(hba, hba->wc_desc);
579 ufs_info_show_conf_desc(hba->wc_desc);
580
581 err = compair_conf_desp(hba->wc_desc, hba->rc_desc);
582 printf("compair_conf_desp: 0x%x\n", err);
583
584 if (!err)
585 goto out;
586
587 err = ufs_write_configuration_desc(hba, hba->wc_desc);
588 if (err)
589 dev_err(hba->dev, "%s: Failed write conf info. err = %d\n", __func__, err);
590
591 err = _ufs_start(hba);
592 if (err)
593 return err;
594 out:
595 ufs_info_show_dev_desc(hba->dev_desc);
596
597 ufs_set_ref_clk(hba);
598
599 return set_boot_lu_enable(hba);
600 }
601 #endif
602