1 /*
2 * Copyright (c) 2020 HiSilicon (Shanghai) Technologies CO., LIMITED.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the
6 * Free Software Foundation; either version 2 of the License, or (at your
7 * option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
16 *
17 * Description: ufs driver
18 */
19
20 #include <common.h>
21 #include <malloc.h>
22 #include <asm/dma-mapping.h>
23 #include <cpu_func.h>
24 #include <ufs.h>
25 #include "ufs_hisi.h"
26 #include "scsi.h"
27
28 #define UFS_CID_SIZE 4
29 #define SERIAL_NUM_SIZE 12
30
31 struct dwc_ufs_hba g_dwc_host[MAX_DEVICE];
32 struct ufs_descriptor g_ufs_desc;
33 struct ufs g_ufs_info;
34
35 static uint8_t g_tx_lane_num[MAX_DEVICE] = {0};
36 static uint8_t g_rx_lane_num[MAX_DEVICE] = {0};
37 static int g_wlun = 0;
38 static unsigned int g_ufs_cid[UFS_CID_SIZE];
39
40 struct ufs_adapt_reg {
41 unsigned int addr;
42 unsigned int value[7]; /* 7 mode param */
43 };
44
45 static struct ufs_adapt_reg reglist_pmc[] = {
46 /* addr G3RB G3RA G2RB G2RA G1RB G1RA PWM */
47 {0x007e0000, { 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}},
48 {0x007e0001, { 0x05, 0x05, 0x05, 0x05, 0x05, 0x05, 0x00}},
49 {0x00fc0004, { 0x1f, 0x1f, 0x1b, 0x1b, 0x1b, 0x1b, 0x00}},
50 {0x00fc0005, { 0x1f, 0x1f, 0x1b, 0x1b, 0x1b, 0x1b, 0x00}},
51 {0x00fd0004, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}},
52 {0x00fd0005, { 0x00, 0x00, 0x00, 0x00, 0x01, 0x01, 0x00}},
53 {0x007f0000, { 0x24, 0x22, 0x21, 0x21, 0x13, 0x13, 0x00}},
54 {0x007f0001, { 0x24, 0x22, 0x21, 0x21, 0x13, 0x13, 0x00}},
55 {0x007d0000, { 0x24, 0x22, 0x21, 0x21, 0x13, 0x13, 0x00}},
56 {0x007d0001, { 0x24, 0x22, 0x21, 0x21, 0x13, 0x13, 0x00}},
57 {0x00370000, { 0x26, 0x26, 0x23, 0x23, 0x20, 0x20, 0x00}},
58 {0x00370001, { 0x26, 0x26, 0x23, 0x23, 0x20, 0x20, 0x00}},
59 {0x007b0000, { 0x26, 0x26, 0x23, 0x23, 0x20, 0x20, 0x00}},
60 {0x007b0001, { 0x26, 0x26, 0x23, 0x23, 0x20, 0x20, 0x00}}
61 };
62
adapt_mode_change(struct pwr_mode_params * pmp)63 static void adapt_mode_change(struct pwr_mode_params *pmp)
64 {
65 int i, mode;
66
67 get_local_dwc_host();
68 if (dwc_host->manufacturer_id == UFS_MANUFACTURER_ID_HYNIX) {
69 printf("H**** device must set VS_DebugSaveConfigTime 0x10\n");
70 /* VS_DebugSaveConfigTime */
71 send_uic_command(DME_SET, 0xd0a00000, 0x0, 0x10);
72 /* sync length */
73 send_uic_command(DME_SET, 0x15560000, 0x0, 0x48);
74 }
75
76 #if defined(COMBO_PHY_V120)
77 if (pmp->pwr_mode == FAST_MODE || pmp->pwr_mode == FASTAUTO_MODE) {
78 mode = 8 - pmp->tx_gear * 2 - pmp->hs_series; /* mode[8 - gear * 2 - rate] */
79 } else {
80 mode = 6; /* mode[6] : PWM */
81 return; /* PWM is unused here */
82 }
83
84 for (i = 0; i < sizeof(reglist_pmc) / sizeof(reglist_pmc[0]); i++)
85 send_uic_command(DME_SET, reglist_pmc[i].addr, 0x0, reglist_pmc[i].value[mode]);
86 #endif
87 }
88
ufs_read_string_index(char * dest,uint8_t desc_index)89 static int ufs_read_string_index(char *dest, uint8_t desc_index)
90 {
91 struct desc_params params;
92 struct dwc_ufs_query_upiu *req_upiu = NULL;
93 void *resp_upiu = NULL;
94 uint8_t *p = NULL;
95 int ret;
96 int len;
97 int i;
98
99 get_local_dwc_host();
100 /* use slot 0 default */
101 resp_upiu = dwc_host->lrb[0].resp_upiu;
102 req_upiu = (struct dwc_ufs_query_upiu *)(dwc_host->lrb[0].cmd_upiu);
103
104 params.req_upiu = req_upiu;
105 params.part_desc = NULL;
106 params.opcode = READ_DESC_OPCODE;
107 params.desc_idn = STRING_DESC;
108 params.desc_index = desc_index;
109 params.length = STRING_DESC_LENGTH;
110 modify_desc_upiu(¶ms);
111
112 ret = read_descriptor(req_upiu, &resp_upiu);
113 if (ret != UFS_OK) {
114 printf("read descriptor fail. ret = %d\n", ret);
115 return ret;
116 }
117
118 /* get string info */
119 p = ((u8 *)resp_upiu + QUERY_RESPONSE_HEAD_OFFSET);
120 len = p[0] / 2; /* 2 byte unicode */
121
122 for (i = 1; i < len; i++)
123 dest[i - 1] = p[2 * i + 1]; /* 2 byte unicode */
124 dest[len - 1] = '\0';
125
126 return UFS_OK;
127 }
128
ufs_read_string_descriptor(void)129 static int ufs_read_string_descriptor(void)
130 {
131 int ret;
132
133 /* manufacturer name */
134 ret = ufs_read_string_index(g_ufs_desc.str_desc.manufacturer_name,
135 g_ufs_desc.dev_desc.i_manufacturer_name);
136 if (ret != UFS_OK) {
137 printf("get manufacturer name fail\n");
138 return UFS_ERR;
139 }
140
141 /* product name */
142 ret = ufs_read_string_index(g_ufs_desc.str_desc.product_name,
143 g_ufs_desc.dev_desc.i_product_name);
144 if (ret != UFS_OK) {
145 printf("get product name fail\n");
146 return UFS_ERR;
147 }
148
149 /* serial number */
150 ret = ufs_read_string_index(g_ufs_desc.str_desc.serial_number,
151 g_ufs_desc.dev_desc.i_serial_number);
152 if (ret != UFS_OK) {
153 printf("get serial number fail\n");
154 return UFS_ERR;
155 }
156
157 /* oem id */
158 ret = ufs_read_string_index(g_ufs_desc.str_desc.oem_id,
159 g_ufs_desc.dev_desc.i_oem_id);
160 if (ret != UFS_OK) {
161 printf("get oem id fail\n");
162 return UFS_ERR;
163 }
164
165 return UFS_OK;
166 }
167
ufs_read_descriptor(void * dest,uint8_t idn,uint8_t index,uint16_t length)168 static int ufs_read_descriptor(void *dest, uint8_t idn, uint8_t index, uint16_t length)
169 {
170 struct desc_params params;
171 struct dwc_ufs_query_upiu *req_upiu = NULL;
172 void *resp_upiu = NULL;
173 int ret;
174
175 get_local_dwc_host();
176 /* use slot 0 default */
177 resp_upiu = dwc_host->lrb[0].resp_upiu;
178 req_upiu = (struct dwc_ufs_query_upiu *)(dwc_host->lrb[0].cmd_upiu);
179
180 params.req_upiu = req_upiu;
181 params.part_desc = NULL;
182 params.opcode = READ_DESC_OPCODE;
183 params.desc_idn = idn;
184 params.desc_index = index;
185 params.length = length;
186 modify_desc_upiu(¶ms);
187
188 ret = read_descriptor(req_upiu, &resp_upiu);
189 if (ret != UFS_OK) {
190 printf("read descriptor fail. ret = %d\n", ret);
191 return ret;
192 }
193 memcpy(dest, (void *)((u8 *)resp_upiu + QUERY_RESPONSE_HEAD_OFFSET), length);
194
195 return UFS_OK;
196 }
197
ufs_read_unit_descriptor(void)198 static int ufs_read_unit_descriptor(void)
199 {
200 int ret;
201 int i;
202
203 /* Unit Descriptor */
204 for (i = 0; i < UNIT_DESCS_COUNT; i++) {
205 ret = ufs_read_descriptor((void *)(&g_ufs_desc.unit_desc.unit_index_desc[i]),
206 UNIT_DESC, i, UNIT_DESC_LENGTH);
207 if (ret != UFS_OK) {
208 printf("get unit[%d] fail\n", i);
209 return UFS_ERR;
210 }
211 }
212
213 /* RPMB Descriptor */
214 ret = ufs_read_descriptor((void *)(&g_ufs_desc.unit_desc.unit_rpmb_desc),
215 UNIT_DESC, 0xC4, UNIT_DESC_LENGTH);
216 if (ret != UFS_OK) {
217 printf("get rpmb fail\n");
218 return UFS_ERR;
219 }
220
221 return UFS_OK;
222 }
223
ufs_info_show_portion(void)224 static void ufs_info_show_portion(void)
225 {
226 printf("Manufacturer ID: 0x%x\n", to_bigendian16(g_ufs_desc.dev_desc.w_manufacturer_id));
227 printf("Product Name: %s\n", g_ufs_desc.str_desc.product_name);
228
229 printf("Speed Mode: %s Gear-%d Rate-%c Lanes-%d\n",
230 ((DEFAULT_MODE == SLOW_MODE) ? "Slow" :
231 ((DEFAULT_MODE == SLOWAUTO_MODE) ? "SlowAuto" :
232 ((DEFAULT_MODE == FAST_MODE) ? "Fast" : "FastAuto"))),
233 DEFAULT_GEAR, (DEFAULT_RATE == 1) ? 'A' : 'B', DEFAULT_LANE);
234 printf("High Capacity: Yes\n");
235 printf("Capacity: %lld\n", g_ufs_info.capacity);
236 }
237
ufs_info_show_dev_desc(void)238 static void ufs_info_show_dev_desc(void)
239 {
240 struct ufs_device_descriptor dev;
241
242 dev = g_ufs_desc.dev_desc;
243
244 printf("---------------------------\n");
245 printf("---UFS Device Descriptor---\n");
246 printf("---------------------------\n");
247 printf("bLength: 0x%x\n", dev.b_length);
248 printf("bDescriptorIDN: 0x%x\n", dev.b_descriptor_idn);
249 printf("bDevice: 0x%x\n", dev.b_device);
250 printf("bDeviceClass: 0x%x\n", dev.b_device_class);
251 printf("bDeviceSubClass: 0x%x\n", dev.b_device_sub_class);
252 printf("bProtocol: 0x%x\n", dev.b_protocol);
253 printf("bNumberLU: 0x%x\n", dev.b_number_lu);
254 printf("bNumberWLU: 0x%x\n", dev.b_number_wlu);
255 printf("bBootEnable: 0x%x\n", dev.b_boot_enable);
256 printf("bDescrAccessEn: 0x%x\n", dev.b_descr_access_en);
257 printf("bInitPowerMode: 0x%x\n", dev.b_init_power_mode);
258 printf("bHighPriorityLUN: 0x%x\n", dev.b_high_priority_lun);
259 printf("bSecureRemovalType: 0x%x\n", dev.b_secure_removal_type);
260 printf("bSecurityLU: 0x%x\n", dev.b_security_lu);
261 printf("bBackgroundOpsTermLat: 0x%x\n", dev.b_background_ops_term_lat);
262 printf("bInitActiveICCLevel: 0x%x\n", dev.b_init_active_icc_level);
263 printf("wSpecVersion: 0x%x\n", to_bigendian16(dev.w_spec_version));
264 printf("wManufactureDate: 0x%x\n", to_bigendian16(dev.w_manufacture_date));
265 printf("iManufacturerName: 0x%x\n", dev.i_manufacturer_name);
266 printf("iProductName: 0x%x\n", dev.i_product_name);
267 printf("iSerialNumber: 0x%x\n", dev.i_serial_number);
268 printf("iOemID: 0x%x\n", dev.i_oem_id);
269 printf("wManufacturerID: 0x%x\n", to_bigendian16(dev.w_manufacturer_id));
270 printf("bUD0BaseOffset: 0x%x\n", dev.b_ud_0base_offset);
271 printf("bUDConfigPLength: 0x%x\n", dev.b_ud_config_plength);
272 printf("bDeviceRTTCap: 0x%x\n", dev.b_device_rtt_cap);
273 printf("wPeriodicRTCUpdate: 0x%x\n", to_bigendian16(dev.w_periodic_rtc_update));
274 printf("bUFSFeatureSupport: 0x%x\n", dev.b_ufs_feature_support);
275 printf("bFFUTimeout: 0x%x\n", dev.b_ffu_timeout);
276 printf("bQueueDepth: 0x%x\n", dev.b_queue_depth);
277 printf("wDeviceVersion: 0x%x\n", to_bigendian16(dev.w_device_version));
278 printf("bNumSecureWPArea: 0x%x\n", dev.b_num_secure_wp_area);
279 printf("dPSAMaxDataSize: 0x%x\n", to_bigendian32(dev.d_psa_max_data_size));
280 printf("bPSAStateTimeout: 0x%x\n", dev.b_psa_state_timeout);
281 printf("iProductRevisionLevel: 0x%x\n", dev.i_product_revision_level);
282 }
283
ufs_info_show_geo_desc(void)284 static void ufs_info_show_geo_desc(void)
285 {
286 struct ufs_geometry_descriptor geo;
287
288 geo = g_ufs_desc.geo_desc;
289
290 printf("-----------------------------\n");
291 printf("---UFS Geometry Descriptor---\n");
292 printf("-----------------------------\n");
293 printf("bLength: 0x%x\n", geo.b_length);
294 printf("bDescriptorIDN: 0x%x\n", geo.b_descriptor_idn);
295 printf("bMediaTechnology: 0x%x\n", geo.b_media_technology);
296 printf("qTotalRawDeviceCapacity: 0x%llx\n", cpu_to_be64(geo.q_total_raw_device_capacity));
297 printf("bMaxNumberLU: 0x%x\n", geo.b_max_number_lu);
298 printf("dSegmentSize: 0x%x\n", to_bigendian32(geo.d_segment_size));
299 printf("bAllocationUnitSize: 0x%x\n", geo.b_allocation_unit_size);
300 printf("bMinAddrBlockSize: 0x%x\n", geo.b_min_addr_block_size);
301 printf("bOptimalReadBlockSize: 0x%x\n", geo.b_optimal_read_block_size);
302 printf("bOptimalWriteBlockSize: 0x%x\n", geo.b_optimal_write_block_size);
303 printf("bMaxInBufferSize: 0x%x\n", geo.b_max_in_buffer_size);
304 printf("bMaxOutBufferSize: 0x%x\n", geo.b_max_out_buffer_size);
305 printf("bRPMB_ReadWriteSize: 0x%x\n", geo.b_rpmb_read_write_size);
306 printf("bDynamicCapacityResourcePolicy: 0x%x\n", geo.b_dynamic_capacity_resource_policy);
307 printf("bDataOrdering: 0x%x\n", geo.b_data_ordering);
308 printf("bMaxContexIDNumber: 0x%x\n", geo.b_max_contex_id_number);
309 printf("bSysDataTagUnitSize: 0x%x\n", geo.b_sys_data_tag_unit_size);
310 printf("bSysDataTagResSize: 0x%x\n", geo.b_sys_data_tag_res_size);
311 printf("bSupportedSecRTypes: 0x%x\n", geo.b_supported_sec_rtypes);
312 printf("wSupportedMemoryTypes: 0x%x\n", to_bigendian16(geo.w_supported_memory_types));
313 printf("dSystemCodeMaxNAllocU: 0x%x\n", to_bigendian32(geo.d_system_code_max_alloc_u));
314 printf("wSystemCodeCapAdjFac: 0x%x\n", to_bigendian16(geo.w_system_code_cap_adj_fac));
315 printf("dNonPersistMaxNAllocU: 0x%x\n", to_bigendian32(geo.d_non_persist_max_alloc_u));
316 printf("wNonPersistCapAdjFac: 0x%x\n", to_bigendian16(geo.w_non_persist_cap_adj_fac));
317 printf("dEnhanced1MaxNAllocU: 0x%x\n", to_bigendian32(geo.d_enhanced1_max_alloc_u));
318 printf("wEnhanced1CapAdjFac: 0x%x\n", to_bigendian16(geo.w_enhanced1_cap_adj_fac));
319 printf("dEnhanced2MaxNAllocU: 0x%x\n", to_bigendian32(geo.d_enhanced2_max_alloc_u));
320 printf("wEnhanced2CapAdjFac: 0x%x\n", to_bigendian16(geo.w_enhanced2_cap_adj_fac));
321 printf("dEnhanced3MaxNAllocU: 0x%x\n", to_bigendian32(geo.d_enhanced3_max_alloc_u));
322 printf("wEnhanced3CapAdjFac: 0x%x\n", to_bigendian16(geo.w_enhanced3_cap_adj_fac));
323 printf("dEnhanced4MaxNAllocU: 0x%x\n", to_bigendian32(geo.d_enhanced4_max_alloc_u));
324 printf("wEnhanced4CapAdjFac: 0x%x\n", to_bigendian16(geo.w_enhanced4_cap_adj_fac));
325 printf("dOptimalLogicalBlockSize: 0x%x\n", to_bigendian32(geo.d_optimal_logical_block_size));
326 }
327
ufs_info_show_unit_desc(void)328 static void ufs_info_show_unit_desc(void)
329 {
330 struct ufs_unit_index_descriptror unit;
331 struct ufs_unit_rpmb_descriptror rpmb;
332 int i;
333
334 for (i = 0; i < UNIT_DESCS_COUNT; i++) {
335 unit = g_ufs_desc.unit_desc.unit_index_desc[i];
336
337 printf("----------------------------\n");
338 printf("---UFS Unit %d Descriptor---\n", i);
339 printf("----------------------------\n");
340 printf("bLength: 0x%x\n", unit.b_length);
341 printf("bDescriptorIDN: 0x%x\n", unit.b_descriptor_idn);
342 printf("bUnitIndex: 0x%x\n", unit.b_unit_index);
343 printf("bLUEnable: 0x%x\n", unit.b_lu_enable);
344 printf("bBootLunID: 0x%x\n", unit.b_boot_lun_id);
345 printf("bLUWriteProtect: 0x%x\n", unit.b_lu_write_protect);
346 printf("bLUQueueDepth: 0x%x\n", unit.b_lu_queue_depth);
347 printf("bPSASensitive: 0x%x\n", unit.b_psa_sensitive);
348 printf("bMemoryType: 0x%x\n", unit.b_memory_type);
349 printf("bDataReliability: 0x%x\n", unit.b_data_reliability);
350 printf("bLogicalBlockSize: 0x%x\n", unit.b_logical_block_size);
351 printf("qLogicalBlockCount: 0x%llx\n", cpu_to_be64(unit.q_logical_block_count));
352 printf("dEraseBlockSize: 0x%x\n", to_bigendian32(unit.d_erase_block_size));
353 printf("bProvisioningType: 0x%x\n", unit.b_provisioning_type);
354 printf("qPhyMemResourceCount: 0x%x\n", to_bigendian32(unit.q_phy_mem_resource_count));
355 printf("wContextCapabilities: 0x%x\n", to_bigendian16(unit.w_context_capabilities));
356 printf("bLargeUnitGranularity_M1: 0x%x\n", unit.b_large_unit_granularity_m1);
357 }
358
359 rpmb = g_ufs_desc.unit_desc.unit_rpmb_desc;
360
361 printf("------------------------------\n");
362 printf("---UFS Unit RPMB Descriptor---\n");
363 printf("------------------------------\n");
364 printf("bLength: 0x%x\n", rpmb.b_length);
365 printf("bDescriptorIDN: 0x%x\n", rpmb.b_descriptor_idn);
366 printf("bUnitIndex: 0x%x\n", rpmb.b_unit_index);
367 printf("bLUEnable: 0x%x\n", rpmb.b_lu_enable);
368 printf("bBootLunID: 0x%x\n", rpmb.b_boot_lun_id);
369 printf("bLUWriteProtect: 0x%x\n", rpmb.b_lu_write_protect);
370 printf("bLUQueueDepth: 0x%x\n", rpmb.b_lu_queue_depth);
371 printf("bPSASensitive: 0x%x\n", rpmb.b_psa_sensitive);
372 printf("bMemoryType: 0x%x\n", rpmb.b_memory_type);
373 printf("bLogicalBlockSize: 0x%x\n", rpmb.b_logical_block_size);
374 printf("qLogicalBlockCount: 0x%llx\n", cpu_to_be64(rpmb.q_logical_block_count));
375 printf("dEraseBlockSize: 0x%x\n", to_bigendian32(rpmb.d_erase_block_size));
376 printf("bProvisioningType: 0x%x\n", rpmb.b_provisioning_type);
377 printf("qPhyMemResourceCount: 0x%x\n", to_bigendian32(rpmb.q_phy_mem_resource_count));
378 }
379
ufs_info_show_conf_desc(void)380 static void ufs_info_show_conf_desc(void)
381 {
382 struct ufs_dev_desc_configuration_param dev;
383 struct ufs_unit_desc_configuration_param unit;
384 int i;
385
386 dev = g_ufs_desc.conf_desc.dev_desc_conf_param;
387
388 printf("----------------------------------------\n");
389 printf("---UFS Device Descriptor Config Param---\n");
390 printf("----------------------------------------\n");
391 printf("bLength: 0x%x\n", dev.b_length);
392 printf("bDescriptorIDN: 0x%x\n", dev.b_descriptor_idn);
393 printf("bConfDescContinue: 0x%x\n", dev.b_conf_desc_continue);
394 printf("bBootEnable: 0x%x\n", dev.b_boot_enable);
395 printf("bDescrAccessEn: 0x%x\n", dev.b_descr_access_en);
396 printf("bInitPowerMode: 0x%x\n", dev.b_init_power_mode);
397 printf("bHighPriorityLUN: 0x%x\n", dev.b_high_priority_lun);
398 printf("bSecureRemovalType: 0x%x\n", dev.b_secure_removal_type);
399 printf("bInitActiveICCLevel: 0x%x\n", dev.b_init_active_icc_level);
400 printf("wPeriodicRTCUpdate: 0x%x\n", to_bigendian16(dev.w_periodic_rtc_update));
401
402 for (i = 0; i < UNIT_DESCS_COUNT; i++) {
403 unit = g_ufs_desc.conf_desc.unit_desc_conf_param[i];
404
405 printf("-----------------------------------------\n");
406 printf("---UFS Unit %d Descriptor Config Param---\n", i);
407 printf("-----------------------------------------\n");
408 printf("bLUEnable: 0x%x\n", unit.b_lu_enable);
409 printf("bBootLunID: 0x%x\n", unit.b_boot_lun_id);
410 printf("bLUWriteProtect: 0x%x\n", unit.b_lu_write_protect);
411 printf("bMemoryType: 0x%x\n", unit.b_memory_type);
412 printf("dNumAllocUnits: 0x%x\n", to_bigendian32(unit.d_num_alloc_units));
413 printf("bDataReliability: 0x%x\n", unit.b_data_reliability);
414 printf("bLogicalBlockSize: 0x%x\n", unit.b_logical_block_size);
415 printf("bProvisioningType: 0x%x\n", unit.b_provisioning_type);
416 printf("wContextCapabilities: 0x%x\n", to_bigendian16(unit.w_context_capabilities));
417 }
418 }
419
ufs_info_show_str_desc(void)420 static void ufs_info_show_str_desc(void)
421 {
422 struct ufs_string_descriptor str;
423
424 str = g_ufs_desc.str_desc;
425
426 printf("---------------------------\n");
427 printf("---UFS String Descriptor---\n");
428 printf("---------------------------\n");
429 printf("Manufacturer Name: %s\n", str.manufacturer_name);
430 printf("Product Name: %s\n", str.product_name);
431 printf("Serial Number: %s\n", str.serial_number);
432 printf("Oem ID: %s\n", str.oem_id);
433 }
434
ufs_info_show_heal_desc(void)435 static void ufs_info_show_heal_desc(void)
436 {
437 struct ufs_health_descriptor heal;
438
439 heal = g_ufs_desc.heal_desc;
440
441 printf("---------------------------\n");
442 printf("---UFS Health Descriptor---\n");
443 printf("---------------------------\n");
444 printf("bLength: 0x%x\n", heal.b_length);
445 printf("bDescriptorIDN: 0x%x\n", heal.b_descriptor_idn);
446 printf("bPreEOLInfo: 0x%x\n", heal.b_pre_eol_info);
447 printf("bDeviceLifeTimeEstA: 0x%x\n", heal.b_device_life_time_est_a);
448 printf("bDeviceLifeTimeEstB: 0x%x\n", heal.b_device_life_time_est_b);
449 }
450
ufs_info_show_intr_desc(void)451 static void ufs_info_show_intr_desc(void)
452 {
453 struct ufs_interconnect_descriptor intr;
454
455 intr = g_ufs_desc.intr_desc;
456
457 printf("---------------------------------\n");
458 printf("---UFS Interconnect Descriptor---\n");
459 printf("---------------------------------\n");
460 printf("bLength: 0x%x\n", intr.b_length);
461 printf("bDescriptorIDN: 0x%x\n", intr.b_descriptor_idn);
462 printf("bcdUniproVersion: 0x%x\n", to_bigendian16(intr.bcd_unipro_version));
463 printf("bcdMphyVersion: 0x%x\n", to_bigendian16(intr.bcd_mphy_version));
464 }
465
ufs_info_show_all(void)466 static void ufs_info_show_all(void)
467 {
468 ufs_info_show_portion();
469 ufs_info_show_dev_desc();
470 ufs_info_show_conf_desc();
471 ufs_info_show_unit_desc();
472 ufs_info_show_intr_desc();
473 ufs_info_show_str_desc();
474 ufs_info_show_geo_desc();
475 ufs_info_show_heal_desc();
476 }
477
ufs_desc_init(void)478 static int ufs_desc_init(void)
479 {
480 int ret;
481
482 if (g_ufs_desc.desc_is_init == 1)
483 return UFS_OK;
484
485 ret = ufs_read_descriptor((void *)(&g_ufs_desc.conf_desc),
486 CONFIGURATION_DESC, 0, CONFIGURATION_DESC_LENGTH);
487 if (ret != UFS_OK) {
488 printf("read configuration descriptor fail\n");
489 return UFS_ERR;
490 }
491
492 ret = ufs_read_unit_descriptor();
493 if (ret != UFS_OK) {
494 printf("read unit descriptor fail\n");
495 return UFS_ERR;
496 }
497
498 ret = ufs_read_descriptor((void *)(&g_ufs_desc.intr_desc),
499 INTERCONNECT_DESC, 0, INTERCONNECT_DESC_LENGTH);
500 if (ret != UFS_OK) {
501 printf("read interconnect descriptor fail\n");
502 return UFS_ERR;
503 }
504
505 ret = ufs_read_descriptor((void *)(&g_ufs_desc.heal_desc),
506 HEALTH_DESC, 0, HEALTH_DESC_LENGTH);
507 if (ret != UFS_OK) {
508 printf("read health descriptor fail\n");
509 return UFS_ERR;
510 }
511
512 g_ufs_desc.desc_is_init = 1;
513
514 return UFS_OK;
515 }
516
ufs_show_desc_info(enum info_show_type type)517 int ufs_show_desc_info(enum info_show_type type)
518 {
519 int ret;
520
521 ret = ufs_desc_init();
522 if (ret != UFS_OK)
523 return ret;
524
525 switch (type) {
526 case UFS_INFO_SHOW_BASIC:
527 ufs_info_show_portion();
528 break;
529 case UFS_INFO_SHOW_ALL:
530 ufs_info_show_all();
531 break;
532 case UFS_INFO_SHOW_DEVICE_DESC:
533 ufs_info_show_dev_desc();
534 break;
535 case UFS_INFO_SHOW_CONFIGURATION_DESC:
536 ufs_info_show_conf_desc();
537 break;
538 case UFS_INFO_SHOW_UNIT_DESC:
539 ufs_info_show_unit_desc();
540 break;
541 case UFS_INFO_SHOW_INTERCONNECT_DESC:
542 ufs_info_show_intr_desc();
543 break;
544 case UFS_INFO_SHOW_STRING_DESC:
545 ufs_info_show_str_desc();
546 break;
547 case UFS_INFO_SHOW_GEOMETRY_DESC:
548 ufs_info_show_geo_desc();
549 break;
550 case UFS_INFO_SHOW_HEALTH_DESC:
551 ufs_info_show_heal_desc();
552 break;
553 default:
554 printf("unknown cmd\n");
555 break;
556 }
557
558 return UFS_OK;
559 }
560
ufs_info_init(void)561 static void ufs_info_init(void)
562 {
563 uint32_t lba;
564 int ret;
565
566 g_ufs_info.blocksize = LOGICAL_BLK_SIZE;
567 g_ufs_info.block_read = ufs_read_storage;
568 g_ufs_info.block_write = ufs_write_storage;
569 g_ufs_info.boot_block_write = ufs_write_boot_storage;
570
571 ret = ufs_read_capacity(&lba);
572 if (ret != UFS_SUCCESS)
573 return;
574
575 g_ufs_info.capacity = (uint64_t)lba * LOGICAL_BLK_SIZE;
576 }
577
get_ufs_info(void)578 struct ufs *get_ufs_info(void)
579 {
580 return &g_ufs_info;
581 }
582
ufshci_dump(void)583 void ufshci_dump(void)
584 {
585 printf("===== UFSHCI REGISTER DUMP =====\n");
586 printf("CAP: 0x%08x||VER: 0x%08x\n",
587 dwc_ufs_read_reg(UFS_CAP_OFF),
588 dwc_ufs_read_reg(UFS_VER_OFF));
589 printf("HCPID: 0x%08x||HCMID: 0x%08x\n",
590 dwc_ufs_read_reg(UFS_HCPID_OFF),
591 dwc_ufs_read_reg(UFS_HCMID_OFF));
592 printf("AHIT: 0x%08x||IS: 0x%08x\n",
593 dwc_ufs_read_reg(UFS_AHIT_OFF),
594 dwc_ufs_read_reg(UFS_IS_OFF));
595 printf("IE: 0x%08x||HCS: 0x%08x\n",
596 dwc_ufs_read_reg(UFS_IE_OFF),
597 dwc_ufs_read_reg(UFS_HCS_OFF));
598 printf("HCE: 0x%08x||UECPA: 0x%08x\n",
599 dwc_ufs_read_reg(UFS_HCE_OFF),
600 dwc_ufs_read_reg(UFS_UECPA_OFF));
601 printf("UECDL: 0x%08x||UECN: 0x%08x\n",
602 dwc_ufs_read_reg(UFS_UECDL_OFF),
603 dwc_ufs_read_reg(UFS_UECN_OFF));
604 printf("UECT: 0x%08x||UECDME: 0x%08x\n",
605 dwc_ufs_read_reg(UFS_UECT_OFF),
606 dwc_ufs_read_reg(UFS_UECDME_OFF));
607 printf("UTRIACR: 0x%08x||UTRLBA: 0x%08x\n",
608 dwc_ufs_read_reg(UFS_UTRIACR_OFF),
609 dwc_ufs_read_reg(UFS_UTRLBA_OFF));
610 printf("UTRLBAU: 0x%08x||UTRLDBR: 0x%08x\n",
611 dwc_ufs_read_reg(UFS_UTRLBAU_OFF),
612 dwc_ufs_read_reg(UFS_UTRLDBR_OFF));
613 printf("UTRLCLR: 0x%08x||UTRLRSR: 0x%08x\n",
614 dwc_ufs_read_reg(UFS_UTRLCLR_OFF),
615 dwc_ufs_read_reg(UFS_UTRLRSR_OFF));
616 printf("UTMRLBA: 0x%08x||UTMRLBAU: 0x%08x\n",
617 dwc_ufs_read_reg(UFS_UTMRLBA_OFF),
618 dwc_ufs_read_reg(UFS_UTMRLBAU_OFF));
619 printf("UTMRLDBR: 0x%08x||UTMRLCLR: 0x%08x\n",
620 dwc_ufs_read_reg(UFS_UTMRLDBR_OFF),
621 dwc_ufs_read_reg(UFS_UTMRLCLR_OFF));
622 printf("UTMRLRSR: 0x%08x\n",
623 dwc_ufs_read_reg(UFS_UTMRLRSR_OFF));
624 printf("================================\n");
625 }
626
ufs_reg_dump(void)627 void ufs_reg_dump(void)
628 {
629 ufshci_dump();
630 }
631
dwc_ufshcd_get_xfer_req_free_slot(struct dwc_ufs_hba * hba)632 static uint8_t dwc_ufshcd_get_xfer_req_free_slot(struct dwc_ufs_hba *hba)
633 {
634 uint8_t slot;
635
636 for (slot = 0; slot < hba->nutrs; slot++) {
637 if ((hba->outstanding_xfer_reqs & BIT(slot)) == 0)
638 return slot;
639 }
640
641 printf("get xfer free_slot fail\n");
642 return BAD_SLOT;
643 }
644
uic_cmd_read(uint32_t command,uint32_t arg1)645 uint32_t uic_cmd_read(uint32_t command, uint32_t arg1)
646 {
647 int retry;
648 uint32_t reg;
649
650 retry = 100; /* retry 100 times */
651 while (--retry) {
652 if (dwc_ufs_read_reg(UFS_HCS_OFF) & UFS_HCS_UCRDY_BIT)
653 break;
654 ufs_waitms(1);
655 }
656 if (retry <= 0) {
657 printf("%s: wait HCS.UCRDY timeout\n", __func__);
658 ufshci_dump();
659 }
660
661 dwc_ufs_write_reg(UFS_IS_OFF, 0xFFFFFFFF);
662 dwc_ufs_write_reg(UFS_UICCMDARG1_OFF, arg1);
663 dwc_ufs_write_reg(UFS_UICCMDARG2_OFF, 0x0);
664 dwc_ufs_write_reg(UFS_UICCMDARG3_OFF, 0x0);
665
666 dwc_ufs_write_reg(UFS_UICCMD_OFF, (command & 0xFF));
667
668 retry = 100; /* retry 100 times */
669 while (--retry) {
670 if (dwc_ufs_read_reg(UFS_IS_OFF) & UFS_IS_UCCS_BIT)
671 break;
672 ufs_waitms(1);
673 }
674
675 if (retry <= 0) {
676 printf("%s: timeout, cmd:0x%x, arg1:0x%x\n",
677 __func__, command, arg1);
678 ufshci_dump();
679 }
680
681 /* clear interrupt status */
682 dwc_ufs_write_reg(UFS_IS_OFF, UFS_IS_UCCS_BIT);
683
684 if (dwc_ufs_read_reg(UFS_UICCMDARG2_OFF) & 0xFF) {
685 printf("%s:response error\n", __func__);
686 ufshci_dump();
687 }
688
689 if (dwc_ufs_read_reg(UFS_IS_OFF) & UFS_IS_UE_BIT) {
690 printf("%s:UFS_IS_UE_BIT error\n", __func__);
691 /* clear interrupt status */
692 /* the UE error cause by PA_Init or some other reason,
693 * should clear it, or it will repeatly come out ! */
694 dwc_ufs_write_reg(UFS_IS_OFF, UFS_IS_UE_BIT);
695 ufs_waitms(1);
696 if (dwc_ufs_read_reg(UFS_IS_OFF) & UFS_IS_UE_BIT)
697 printf("%s:can not clear the UE_BIT\n",
698 __func__);
699 }
700
701 /* get uic result */
702 reg = dwc_ufs_read_reg(UFS_UICCMDARG3_OFF);
703
704 return reg;
705 }
706
707 /***************************************************************
708 * send_uic_command
709 * Description: Programs the Command Argument and the Command
710 * Register to send the DME_LINK_STARTUP command
711 * to the device
712 *
713 ***************************************************************/
send_uic_command(uint32_t command,uint32_t arg1,uint32_t arg2,uint32_t arg3)714 void send_uic_command(uint32_t command, uint32_t arg1, uint32_t arg2, uint32_t arg3)
715 {
716 int retry;
717 int val;
718
719 retry = 100; /* retry 100 times */
720 while (--retry) {
721 if (dwc_ufs_read_reg(UFS_HCS_OFF) & UFS_HCS_UCRDY_BIT)
722 break;
723 ufs_waitms(1);
724 }
725 if (retry <= 0) {
726 printf("%s: wait HCS.UCRDY timeout\n", __func__);
727 ufshci_dump();
728 }
729
730 dwc_ufs_write_reg(UFS_IS_OFF, 0xFFFFFFFF);
731 dwc_ufs_write_reg(UFS_UICCMDARG1_OFF, arg1);
732 dwc_ufs_write_reg(UFS_UICCMDARG2_OFF, arg2);
733 dwc_ufs_write_reg(UFS_UICCMDARG3_OFF, arg3);
734
735 dwc_ufs_write_reg(UFS_UICCMD_OFF, (command & 0xFF));
736
737 retry = 500; /* retry 500 times */
738 while (--retry) {
739 if (dwc_ufs_read_reg(UFS_IS_OFF) & UFS_IS_UCCS_BIT)
740 break;
741 ufs_waitms(1);
742 }
743
744 if (retry <= 0)
745 printf("%s: timeout cmd:0x%x, arg1:0x%x, "
746 "arg2:0x%x, arg3:0x%x\n", __func__,
747 command, arg1, arg2, arg3);
748
749 /* clear interrupt status */
750 dwc_ufs_write_reg(UFS_IS_OFF, UFS_IS_UCCS_BIT);
751
752 val = dwc_ufs_read_reg(UFS_UICCMDARG2_OFF);
753 if (val & 0xFF)
754 printf("%s: response error, cmd:0x%x, arg1 is 0x%x, "
755 "response is 0x%x\n", __func__, command, arg1, val);
756
757 if (dwc_ufs_read_reg(UFS_IS_OFF) & UFS_IS_UE_BIT) {
758 printf("%s: UFS_IS_UE_BIT error, cmd:0x%x, arg1 is 0x%x\n",
759 __func__, command, arg1);
760 /* the UE error cause by PA_Init or some other reason,
761 * should clear it, or it will repeatly come out ! */
762 dwc_ufs_write_reg(UFS_IS_OFF, UFS_IS_UE_BIT);
763 ufs_waitms(1);
764 if (dwc_ufs_read_reg(UFS_IS_OFF) & UFS_IS_UE_BIT)
765 printf("%s:can not clear the UE_BIT\n",
766 __func__);
767 }
768 }
769
770 /***************************************************************
771 * setup_snps_mphy_tc
772 * Description: Programs the Unipro and Synopsys Mphy for
773 *
774 ***************************************************************/
setup_snps_mphy_tc(void)775 void setup_snps_mphy_tc(void)
776 {
777 uint32_t retry = 10;
778
779 /* Read the DME_Resest (0xD010) attribute. It must return 0
780 indicating that the reset sequence is completed. */
781 do {
782 if (uic_cmd_read(0x01, 0xD0100000) == 1)
783 break;
784 ufs_waitms(1);
785 } while (retry--);
786 /* DME layer enable ---zhaozhiliang, to delete? */
787 send_uic_command(DME_SET, 0xd0000000, 0x0, 0x01);
788 }
789
ufs_hc_enable(void)790 static int ufs_hc_enable(void)
791 {
792 int retry = 3; /* retry 3 times */
793 int timeout;
794
795 do {
796 dwc_ufs_write_reg(UFS_HCE_OFF, UFS_HCE_RESET_BIT);
797 timeout = 3; /* 3ms timeout */
798 for (;;) {
799 if (dwc_ufs_read_reg(UFS_HCE_OFF) & UFS_HCE_RESET_BIT) {
800 return UFS_SUCCESS;
801 }
802 ufs_waitms(1);
803
804 if (--timeout == 0) {
805 printf("wait HCE time out\n");
806 break;
807 }
808 }
809 } while (--retry > 0);
810
811 return UFS_FAILURE;
812 }
813
ufs_hardware_init(void)814 static void ufs_hardware_init(void)
815 {
816 uint32_t reg;
817
818 reg = readl(CRG_REG_BASE + PERI_CRG96);
819 reg |= BIT_UFS_CLK_EN;
820 writel(reg, CRG_REG_BASE + PERI_CRG96);
821
822 reg = readl(CRG_REG_BASE + PERI_CRG96);
823 reg |= BIT_UFS_SRST_REQ;
824 writel(reg, CRG_REG_BASE + PERI_CRG96);
825
826 udelay(1);
827
828 reg = readl(CRG_REG_BASE + PERI_CRG96);
829 reg &= ~BIT_UFS_SRST_REQ;
830 writel(reg, CRG_REG_BASE + PERI_CRG96);
831
832 udelay(1);
833
834 reg = readl(CRG_REG_BASE + PERI_CRG96);
835 reg |= BIT_UFS_AXI_SRST_REQ;
836 writel(reg, CRG_REG_BASE + PERI_CRG96);
837
838 udelay(1);
839
840 reg = readl(CRG_REG_BASE + PERI_CRG96);
841 reg &= ~BIT_UFS_AXI_SRST_REQ;
842 writel(reg, CRG_REG_BASE + PERI_CRG96);
843
844 reg = readl(MISC_REG_BASE + MISC_CTRL17);
845 reg |= BIT_UFS_ENABLE;
846 writel(reg, MISC_REG_BASE + MISC_CTRL17);
847
848 reg = readl(MISC_REG_BASE + MISC_CTRL17);
849 reg &= ~BIT_DA_UFS_REFCLK_OEN;
850 reg &= ~MASK_DA_UFS_REFCLK_DS;
851 reg |= (BIT_DA_UFS_REFCLK_DS0 |
852 BIT_DA_UFS_REFCLK_DS1 |
853 BIT_DA_UFS_REFCLK_SL);
854 writel(reg, MISC_REG_BASE + MISC_CTRL17);
855
856 reg = readl(MISC_REG_BASE + MISC_CTRL17);
857 reg &= ~BIT_DA_UFS_RESET_OEN;
858 reg &= ~MASK_DA_UFS_RESET_DS;
859 reg |= BIT_DA_UFS_RESET_SL;
860 writel(reg, MISC_REG_BASE + MISC_CTRL17);
861
862 reg = readl(MISC_REG_BASE + MISC_CTRL17);
863 reg &= ~BIT_UFS_PAD_RESET;
864 writel(reg, MISC_REG_BASE + MISC_CTRL17);
865
866 udelay(10); /* delay 10 us */
867
868 reg = readl(MISC_REG_BASE + MISC_CTRL17);
869 reg |= BIT_UFS_PAD_RESET;
870 writel(reg, MISC_REG_BASE + MISC_CTRL17);
871 }
872
phy_init_config(void)873 static void phy_init_config(void)
874 {
875 #if defined(COMBO_PHY_V120)
876 /* Rx SKP_DET_SEL, lane0 */
877 send_uic_command(DME_SET, attr_mrx0(SKP_DET_SEL), 0x0, SKP_DET_SEL_EN);
878 /* Rx SKP_DET_SEL, lane1 */
879 send_uic_command(DME_SET, attr_mrx1(SKP_DET_SEL), 0x0, SKP_DET_SEL_EN);
880
881 /* VCO_AUTO_CHG */
882 send_uic_command(DME_SET, attr_mcb(VCO_AUTO_CHG), 0x0, (VCO_AUTO_CHG_EN | VCO_FORCE_ON_EN));
883 /* RX_SQ_VREF, lane0 */
884 send_uic_command(DME_SET, attr_mrx0(RX_SQ_VREF), 0x0, RX_SQ_VREF_175);
885 /* RX_SQ_VREF, lane1 */
886 send_uic_command(DME_SET, attr_mrx1(RX_SQ_VREF), 0x0, RX_SQ_VREF_175);
887
888 /* Dif_N debouse */
889 send_uic_command(DME_SET, attr_mrx0(0xeb), 0x0, 0x64);
890 /* Dif_N debouse */
891 send_uic_command(DME_SET, attr_mrx1(0xeb), 0x0, 0x64);
892
893 /* dvalid timer */
894 send_uic_command(DME_SET, attr_mrx0(0x0e), 0x0, 0xF0);
895 /* dvalid timer */
896 send_uic_command(DME_SET, attr_mrx1(0x0e), 0x0, 0xF0);
897
898 /* AD_DIF_P_LS_TIMEOUT_VAL, lane0 */
899 send_uic_command(DME_SET, attr_mrx0(AD_DIF_P_LS_TIMEOUT_VAL), 0x0, PWM_PREPARE_TO);
900 /* AD_DIF_P_LS_TIMEOUT_VAL, lane1 */
901 send_uic_command(DME_SET, attr_mrx1(AD_DIF_P_LS_TIMEOUT_VAL), 0x0, PWM_PREPARE_TO);
902
903 send_uic_command(DME_SET, 0x00F40004, 0x0, 0x1); /* RX_EQ_SEL_R */
904 send_uic_command(DME_SET, 0x00F40005, 0x0, 0x1); /* RX_EQ_SEL_R */
905
906 send_uic_command(DME_SET, 0x00F20004, 0x0, 0x3); /* RX_EQ_SEL_C */
907 send_uic_command(DME_SET, 0x00F20005, 0x0, 0x3); /* RX_EQ_SEL_C */
908
909 send_uic_command(DME_SET, 0x00FB0004, 0x0, 0x3); /* RX_VSEL */
910 send_uic_command(DME_SET, 0x00FB0005, 0x0, 0x3); /* RX_VSEL */
911
912 send_uic_command(DME_SET, 0x00f60004, 0x0, 0x2); /* RX_DLF Lane 0 */
913 send_uic_command(DME_SET, 0x00f60005, 0x0, 0x2); /* RX_DLF Lane 1 */
914
915 send_uic_command(DME_SET, 0x000a0004, 0x0, 0x2); /* RX H8_TIMEOUT_VAL, Lane 0 */
916 send_uic_command(DME_SET, 0x000a0005, 0x0, 0x2); /* RX H8_TIMEOUT_VAL, Lane 1 */
917
918 /* in low temperature to solve the PLL's starting of oscillation */
919 send_uic_command(DME_SET, 0x00d40000, 0x0, 0x31); /* RG_PLL_DMY0 */
920 send_uic_command(DME_SET, 0x00730000, 0x0, 0x4); /* TX_PHY_CONFIG II */
921 send_uic_command(DME_SET, 0x00730001, 0x0, 0x4); /* TX_PHY_CONFIG II */
922 #endif /* end of COMBO_PHY_V120 */
923 }
924
ufs_hc_init(void)925 static void ufs_hc_init(void)
926 {
927 uint32_t reg;
928
929 /* get the 1us tick clock, the HCLK is 266Mhz? */
930 dwc_ufs_write_reg(UFS_HCLKDIV_OFF, UFS_HCLKDIV_NORMAL_VALUE);
931
932 phy_init_config();
933
934 send_uic_command(DME_SET, attr_mrx0(MRX_EN), 0x0, MRX_ENABLE); /* RX enable, lane0 */
935 send_uic_command(DME_SET, attr_mrx1(MRX_EN), 0x0, MRX_ENABLE); /* RX enable, lane1 */
936
937 /* disable auto H8 */
938 reg = dwc_ufs_read_reg(UFS_AHIT_OFF);
939 reg = reg & (~UFS_AHIT_AH8ITV_MASK);
940 dwc_ufs_write_reg(UFS_AHIT_OFF, reg);
941
942 setup_snps_mphy_tc();
943 /* disable Vswing change */
944 /* measure the power, can close it */
945 send_uic_command(DME_SET, 0x00C70000, 0x0, 0x3);
946 send_uic_command(DME_SET, 0x00C80000, 0x0, 0x3);
947
948 #ifdef CLOSE_CLK_GATING
949 send_uic_command(DME_SET, 0x00cf0004, 0x0, 0x02); /* RX_STALL */
950 send_uic_command(DME_SET, 0x00cf0005, 0x0, 0x02);
951 send_uic_command(DME_SET, 0x00d00004, 0x0, 0x02); /* RX_SLEEP */
952 send_uic_command(DME_SET, 0x00d00005, 0x0, 0x02);
953 send_uic_command(DME_SET, 0x00cc0004, 0x0, 0x03); /* RX_HS_CLK_EN */
954 send_uic_command(DME_SET, 0x00cc0005, 0x0, 0x03);
955 send_uic_command(DME_SET, 0x00cd0004, 0x0, 0x03); /* RX_LS_CLK_EN */
956 send_uic_command(DME_SET, 0x00cd0005, 0x0, 0x03);
957 #endif
958
959 #if defined(COMBO_PHY_V120)
960 send_uic_command(DME_SET, 0x00c50000, 0x0, 0x03); /* RG_PLL_RXHS_EN */
961 send_uic_command(DME_SET, 0x00c60000, 0x0, 0x03);
962 send_uic_command(DME_SET, 0x00E90004, 0x0, 0x00); /* RX_HS_DATA_VALID_TIMER_VAL0 */
963 send_uic_command(DME_SET, 0x00E90005, 0x0, 0x00);
964 send_uic_command(DME_SET, 0x00EA0004, 0x0, 0x10); /* RX_HS_DATA_VALID_TIMER_VAL1 */
965 send_uic_command(DME_SET, 0x00EA0005, 0x0, 0x10);
966 #endif
967 /* set the HS-prepare length and sync length to MAX value, try to solve
968 the data check error problem, the device seems not receive the write
969 cmd. */
970 /* PA_TxHsG1SyncLength , can not set MPHY's register directly */
971 send_uic_command(DME_SET, 0x15520000, 0x0, 0x4F);
972 /* PA_TxHsG2SyncLength , can not set MPHY's register directly */
973 send_uic_command(DME_SET, 0x15540000, 0x0, 0x4F);
974 /* PA_TxHsG3SyncLength , can not set MPHY's register directly */
975 send_uic_command(DME_SET, 0x15560000, 0x0, 0x4F);
976
977 send_uic_command(DME_SET, 0x00ca0000, 0x0, 0x3); /* pll always on */
978 send_uic_command(DME_SET, 0xD0850000, 0x0, 0x1); /* update */
979
980 /* to check if the unipro have to close the LCC */
981 /* Unipro PA_Local_TX_LCC_Enable */
982 send_uic_command(DME_SET, 0x155E0000, 0x0, 0x0);
983 /* close Unipro VS_Mk2ExtnSupport */
984 send_uic_command(DME_SET, 0xD0AB0000, 0x0, 0x0);
985
986 if (uic_cmd_read(DME_GET, 0xD0AB0000) != 0)
987 printf("Warring!!! close VS_Mk2ExtnSupport failed\n");
988 }
989
ufs_link_startup(void)990 int ufs_link_startup(void)
991 {
992 int retry = 4; /* retry 4 times */
993 int i = 0;
994
995 dwc_ufs_write_reg(UFS_IS_OFF, 0xFFFFFFFF);
996 while (retry-- > 0) {
997 dwc_ufs_write_reg(UFS_UICCMDARG1_OFF, 0);
998 dwc_ufs_write_reg(UFS_UICCMDARG2_OFF, 0);
999 dwc_ufs_write_reg(UFS_UICCMDARG3_OFF, 0);
1000
1001 dwc_ufs_write_reg(UFS_UICCMD_OFF, (UIC_LINK_STARTUP_CMD & 0xFF));
1002
1003 i = 0;
1004 for (;;) {
1005 if (dwc_ufs_read_reg(UFS_IS_OFF) & UFS_IS_UCCS_BIT) {
1006 dwc_ufs_write_reg(UFS_IS_OFF, UFS_IS_UCCS_BIT);
1007 break;
1008 }
1009 ufs_waitms(1);
1010 if (i++ > 200) { /* 200ms timeout */
1011 printf("ufs link startup wait UCCS timeout\n");
1012 break;
1013 }
1014 }
1015
1016 if (dwc_ufs_read_reg(UFS_HCS_OFF) & UFS_HCS_DP_BIT) {
1017 if (dwc_ufs_read_reg(UFS_IS_OFF) & UFS_IS_ULSS_BIT)
1018 dwc_ufs_write_reg(UFS_IS_OFF, UFS_IS_ULSS_BIT);
1019
1020 dwc_ufs_write_reg(UFS_IS_OFF, UFS_IS_UE_BIT);
1021 return UFS_SUCCESS;
1022 }
1023
1024 printf("ufs link startup check DP fail\n");
1025 if (retry <= 0) {
1026 printf("ufs link startup fail\n");
1027 return UFS_LINK_STARTUP_FAIL;
1028 }
1029 i = 0;
1030 for (;;) {
1031 if (dwc_ufs_read_reg(UFS_IS_OFF) &
1032 UFS_IS_ULSS_BIT)
1033 break;
1034 ufs_waitms(1);
1035 if (i++ > 50) { /* 50ms timeout */
1036 printf("ufs link startup wait ULSS timeout\n");
1037 break;
1038 }
1039 }
1040 }
1041
1042 printf("ufs link startup fail\n");
1043 return UFS_LINK_STARTUP_FAIL;
1044 }
1045
update_snum_buff(uint8_t * snum_buf,int sunm_buf_len,uint8_t * resp_buf,int resp_buf_len)1046 static int update_snum_buff(uint8_t *snum_buf, int sunm_buf_len,
1047 uint8_t *resp_buf, int resp_buf_len)
1048 {
1049 uint8_t i;
1050
1051 get_local_dwc_host();
1052
1053 (void)sunm_buf_len;
1054 (void)resp_buf_len;
1055
1056 if (dwc_host->manufacturer_id == UFS_MANUFACTURER_ID_TOSHIBA) {
1057 /*
1058 * toshiba: 20 Byte, every two byte has a prefix of 0x00,
1059 * trim the 0x00 bytes
1060 */
1061 for (i = 0; i < SERIAL_NUM_SIZE - 2; i++) /* exclude last 2 */
1062 snum_buf[i] = resp_buf[2 * i + 1]; /* 2 byte unicode */
1063 /* append two 0x00 byte in the end */
1064 snum_buf[SERIAL_NUM_SIZE - 2] = 0; /* end 2 */
1065 snum_buf[SERIAL_NUM_SIZE - 1] = 0; /* end 1 */
1066 } else if (dwc_host->manufacturer_id == UFS_MANUFACTURER_ID_SAMSUNG) {
1067 /*
1068 * Samsung new ufs device, need 24 Bytes for serial
1069 * number, transfer unicode to 12 bytes
1070 */
1071 for (i = 0; i < SERIAL_NUM_SIZE; i++)
1072 snum_buf[i] = resp_buf[i * 2 + 1]; /* 2 byte unicode */
1073 } else if (dwc_host->manufacturer_id == UFS_MANUFACTURER_ID_HYNIX) {
1074 /* hynix only have 6 Byte, add a 0x00 before every byte */
1075 for (i = 0; i * 2 < SERIAL_NUM_SIZE; i++) { /* 2 byte unicode */
1076 snum_buf[i * 2] = 0x0; /* 2 byte unicode */
1077 snum_buf[i * 2 + 1] = resp_buf[i]; /* 2 byte unicode */
1078 }
1079 } else if (dwc_host->manufacturer_id == UFS_MANUFACTURER_ID_HI1861) {
1080 for (i = 0; i < SERIAL_NUM_SIZE; i++)
1081 snum_buf[i] = resp_buf[i];
1082 } else if (dwc_host->manufacturer_id == UFS_MANUFACTURER_ID_MICRON) {
1083 /* Micron only need 4 Byte */
1084 for (i = 0; i < 4; i++)
1085 snum_buf[i] = resp_buf[i];
1086 for (i = 4; i < SERIAL_NUM_SIZE; i++) /* 4 byte */
1087 snum_buf[i] = 0;
1088 } else if (dwc_host->manufacturer_id == UFS_MANUFACTURER_ID_SANDISK) {
1089 /*
1090 * Sandisk need 24 Bytes for serial number,
1091 * transfer unicode to 12 bytes
1092 */
1093 for (i = 0; i < SERIAL_NUM_SIZE; i++)
1094 snum_buf[i] = resp_buf[i * 2 + 1]; /* 2 byte unicode */
1095 } else {
1096 printf("%s: unknown manufacturer_id (0x%x)\n",
1097 __func__, dwc_host->manufacturer_id);
1098 return -1;
1099 }
1100 return 0;
1101 }
1102
ufs_pack_cid(void)1103 unsigned int *ufs_pack_cid(void)
1104 {
1105 u8 resp_upiu[STRING_DESC_LENGTH]; /* use the slot 0 default */
1106 u8 snum_buf[SERIAL_NUM_SIZE] = {0};
1107 u8 resp_buf[2 * SERIAL_NUM_SIZE + 2]; /* 2 byte unicode */
1108 int ret;
1109
1110 get_local_dwc_host();
1111
1112 ret = ufs_read_descriptor((void *)resp_upiu, STRING_DESC,
1113 g_ufs_desc.dev_desc.i_serial_number, STRING_DESC_LENGTH);
1114 if (ret != UFS_SUCCESS) {
1115 printf("%s: read_descriptor fail. ret = %d\n", __func__, ret);
1116 return NULL;
1117 }
1118 /* 32B query response head + 2B string descriptor head */
1119 memcpy((void *)resp_buf, (void *)(resp_upiu + 2), SERIAL_NUM_SIZE * 2); /* 2 byte unicode */
1120
1121 /* clear and init ufs_cid value */
1122 g_ufs_cid[0] = 0; /* dw 0 */
1123 g_ufs_cid[1] = 0; /* dw 1 */
1124 g_ufs_cid[2] = 0; /* dw 2 */
1125
1126 ret = update_snum_buff(snum_buf, SERIAL_NUM_SIZE, (u8 *)resp_buf,
1127 2 * SERIAL_NUM_SIZE + 2); /* 2 byte unicode */
1128 if (ret != 0)
1129 return NULL;
1130
1131 memcpy(g_ufs_cid, (unsigned int *)snum_buf, (unsigned int)sizeof(snum_buf));
1132 /* dw 3, date 31 - 16, id 15 - 0 */
1133 g_ufs_cid[3] = ((uint32_t)(dwc_host->manufacturer_date) << 16) | dwc_host->manufacturer_id;
1134
1135 return g_ufs_cid;
1136 }
1137
1138 /**
1139 * Number of UTP Transfer Request Slots (NUTRS)
1140 * Number of UTP Task management Request Slots(NUTMRS)
1141 * Auto Hibernate Support (AUTOH8)
1142 */
dwc_ufshcd_read_caps(struct dwc_ufs_hba * hba)1143 static void dwc_ufshcd_read_caps(struct dwc_ufs_hba *hba)
1144 {
1145 hba->caps = dwc_ufs_read_reg(UFS_CAP_OFF);
1146
1147 hba->nutrs = (uint8_t)(hba->caps & DWC_UFS_NUTRS_MASK) + 1;
1148 hba->nutmrs = (uint8_t)
1149 ((hba->caps & DWC_UFS_NUTMRS_MASK) >> DWC_UFS_NUTMRS_SHIFT) + 1;
1150 hba->autoh8 = (uint8_t)
1151 ((hba->caps & DWC_UFS_AUTOH8) >> DWC_UFS_AUTOH8_SHIFT);
1152 }
1153
ufshcd_memory_align(struct dwc_ufs_hba * hba)1154 static void ufshcd_memory_align(struct dwc_ufs_hba *hba)
1155 {
1156 uint32_t utrl_size, utmrl_size, ucdl_size;
1157 uint64_t cur_pool = (uint64_t)(uintptr_t)hba->mem_pool;
1158
1159 utrl_size = sizeof(struct dwc_ufs_utrd) * hba->nutrs;
1160 utmrl_size = sizeof(struct dwc_ufs_utmrd) * hba->nutmrs;
1161 ucdl_size = sizeof(struct dwc_ufs_ucd) * hba->nutrs;
1162
1163 /* Allocate Dma'able memory for UTP Transfer Request List
1164 * UFS spec constraints: Base of List should be aligned to 1024 byte
1165 * (1K boundary)
1166 */
1167 cur_pool = bytes_align_1024(cur_pool);
1168 hba->utrl_base_addr = (struct dwc_ufs_utrd *)(uintptr_t)cur_pool;
1169
1170 ufs_pr_mem("utrl start:0x%llx end:0x%llx sz:0x%x\n",
1171 cur_pool, cur_pool + utrl_size, utrl_size);
1172
1173 /* Allocate Dma'able memory for UTP Task management Request List
1174 * UFS spec constraints: Base of list should be aligned to 1024 byte
1175 * (1K boundary)
1176 */
1177 cur_pool += utrl_size;
1178 cur_pool = bytes_align_1024(cur_pool);
1179 hba->utmrl_base_addr = (struct dwc_ufs_utmrd *)(uintptr_t)cur_pool;
1180
1181 ufs_pr_mem("utmrl start:0x%llx end:0x%llx sz:0x%x\n",
1182 cur_pool, cur_pool + utmrl_size, utmrl_size);
1183
1184 /* Allocate Dma'able memory for UTP Command Descriptor List
1185 * Every Command Descriptor block should be aligned to 128 byte
1186 */
1187 cur_pool += utmrl_size;
1188 cur_pool = bytes_align_128(cur_pool);
1189 hba->ucdl_base_addr = (struct dwc_ufs_ucd *)(uintptr_t)cur_pool;
1190
1191 ufs_pr_mem("ucdl start:0x%llx end:0x%llx sz:0x%x\n",
1192 cur_pool, cur_pool + ucdl_size, ucdl_size);
1193
1194 /* Allocate memory for local reference block */
1195 cur_pool += ucdl_size;
1196 hba->lrb = (struct dwc_ufs_hcd_lrb *)(uintptr_t)cur_pool;
1197
1198 ufs_pr_mem("lrb start:0x%llx sz:0x%x\n",
1199 cur_pool, sizeof(struct dwc_ufs_hcd_lrb) * hba->nutrs);
1200 }
1201
1202 /**
1203 * Allocate memory for Host controller interface.
1204 * Following are the memories allocation by this function.
1205 * - DMA'able memory for UTP transfer request descriptor list
1206 * - DMA'able memory for UTP task management request list
1207 * - DMA'able memory for command table
1208 * - Command UPIU's
1209 * - Response UPIU's
1210 * - PRD tables
1211 * - Non-DMA'able memory for local reference blocks; House keeping
1212 * @hba: Pointer to private structure
1213 *
1214 * Returns 0 for success, non-zero in case of failure
1215 */
dwc_ufshcd_alloc_interface_memory(struct dwc_ufs_hba * hba)1216 static int dwc_ufshcd_alloc_interface_memory(struct dwc_ufs_hba *hba)
1217 {
1218 uint32_t utrl_size, utmrl_size, ucdl_size, lrb_size, total_size;
1219
1220 utrl_size = sizeof(struct dwc_ufs_utrd) * hba->nutrs;
1221 utmrl_size = sizeof(struct dwc_ufs_utmrd) * hba->nutmrs;
1222 ucdl_size = sizeof(struct dwc_ufs_ucd) * hba->nutrs;
1223 lrb_size = sizeof(struct dwc_ufs_hcd_lrb) * hba->nutrs;
1224
1225 total_size = utrl_size + DWC_UTRL_BASE_ALIGN +
1226 utmrl_size + DWC_UTRL_BASE_ALIGN +
1227 ucdl_size + DWC_CMD_BASE_ALIGN + lrb_size;
1228
1229 hba->mem_pool = malloc(total_size);
1230 if (hba->mem_pool == NULL) {
1231 printf("%s: Memory Allocation Failed\n", __func__);
1232 return UFS_ERR;
1233 }
1234 memset(hba->mem_pool, 0, total_size);
1235
1236 ufs_pr_mem("\n@@ ufs memory pool info @@\n");
1237 ufs_pr_mem("poll start:0x%llx sz:0x%x\n",
1238 (uint64_t)(uintptr_t)hba->mem_pool, total_size);
1239 ufshcd_memory_align(hba);
1240
1241 /* Allocate memory for wr_buf, LOGICAL_BLK_SIZE aligned */
1242 hba->wr_buf = memalign(LOGICAL_BLK_SIZE, LOGICAL_BLK_SIZE);
1243 if (hba->wr_buf == NULL) {
1244 printf("%s: Write Read Memory Allocation Failed\n",
1245 __func__);
1246 goto err_alloc;
1247 }
1248 ufs_pr_mem("wrbuf start:0x%llx end:0x%llx sz:0x%x\n",
1249 (uint64_t)(uintptr_t)hba->wr_buf,
1250 (uint64_t)(uintptr_t)hba->wr_buf + LOGICAL_BLK_SIZE,
1251 LOGICAL_BLK_SIZE);
1252
1253 return UFS_OK;
1254
1255 err_alloc:
1256 if (hba->mem_pool)
1257 free(hba->mem_pool);
1258 hba->mem_pool = NULL;
1259
1260 return UFS_ERR;
1261 }
1262
1263 /**
1264 * This function configures interface memory
1265 * - For every UTRD,
1266 * - initializes the Command UPIU base address (Lo and High)
1267 * - response upiu length and offset
1268 * - prdt offset
1269 * - Some key fields are updated in respective lrbs
1270 * - utrd addresses
1271 * - command upiu addresses
1272 * - response upiu addresses
1273 * - prdt base address
1274 * @hba: Pointer to private structure
1275 *
1276 * Returns void
1277 */
dwc_ufshcd_configure_interface_memory(const struct dwc_ufs_hba * hba)1278 static void dwc_ufshcd_configure_interface_memory(const struct dwc_ufs_hba *hba)
1279 {
1280 uint32_t i;
1281 struct dwc_ufs_utrd *utrl; /* Pointer to UTR List */
1282 struct dwc_ufs_ucd *ucdl; /* Pointer to UCD List */
1283 uint64_t ucdl_dma_addr;
1284 uint64_t ucd_dma_addr;
1285
1286 utrl = hba->utrl_base_addr;
1287 ucdl = hba->ucdl_base_addr;
1288 ucdl_dma_addr = (uint64_t)(uintptr_t)hba->ucdl_base_addr; /* UCD list Base address */
1289
1290 /* For as many UTP Transfer Requests in the list */
1291 for (i = 0; i < hba->nutrs; i++) {
1292 /* Configure UTRD with UCD base address */
1293 ucd_dma_addr = ucdl_dma_addr + (uint64_t)sizeof(struct dwc_ufs_ucd) * i;
1294 utrl[i].ucdba = (lower_32_bits(ucd_dma_addr));
1295 utrl[i].ucdbau = (upper_32_bits(ucd_dma_addr));
1296
1297 /* Configure Response UPIU offset and length */
1298 /* These fields are in Dword format */
1299 utrl[i].resp_upiu_offset = to_littleendian16((uint16_t)
1300 ((u32)offsetof(struct dwc_ufs_ucd, resp_upiu) >> UFS_DWORD_SHIFT));
1301 utrl[i].resp_upiu_length = to_littleendian16((uint16_t)
1302 (DWC_UCD_ALIGN >> UFS_DWORD_SHIFT));
1303 /* Configure prdt length and offset */
1304 utrl[i].prdt_offset = to_littleendian16((uint16_t)
1305 ((u32)offsetof(struct dwc_ufs_ucd, prdt) >> UFS_DWORD_SHIFT));
1306 utrl[i].prdt_length = to_littleendian16(0);
1307
1308 /* Update LRB */
1309 hba->lrb[i].utrd = (utrl + i);
1310 hba->lrb[i].cmd_upiu = (struct dwc_ufs_cmd_upiu *)(ucdl + i);
1311 hba->lrb[i].resp_upiu = (struct dwc_ufs_resp_upiu *)(ucdl[i].resp_upiu);
1312 hba->lrb[i].prdt = (struct dwc_ufs_prd *)(ucdl[i].prdt);
1313 }
1314 }
1315
1316 /**
1317 * Get UFS controller state
1318 * @hba: Private structure pointer
1319 *
1320 * Returns TRUE if controller is active, FALSE otherwise
1321 */
dwc_ufshcd_is_hba_active(void)1322 static int dwc_ufshcd_is_hba_active(void)
1323 {
1324 return (dwc_ufs_read_reg(UFS_HCE_OFF) & 0x1) ? UFS_OK : UFS_ERR;
1325 }
1326
1327 /**
1328 * This function performs the initialization of DWC UFS HC descriptors
1329 * with memory base addresses
1330 * Before updating the descriptor addresses, it checks host controller is
1331 * enabled. If not returns error. If enabled, both transfer descriptor
1332 * pointers and tm descriptor pointers are programmed from the drivers
1333 * private structure
1334 * @hba: pointer to drivers private structure
1335 *
1336 * Returns void
1337 */
dwc_ufshcd_initialize_hba_desc_pointers(struct dwc_ufs_hba * hba)1338 static void dwc_ufshcd_initialize_hba_desc_pointers(struct dwc_ufs_hba *hba)
1339 {
1340 /* If the Host Controller is not active, return error */
1341 if (dwc_ufshcd_is_hba_active()) {
1342 printf(" not active , error\n");
1343 return;
1344 }
1345
1346 /* Configure UTRL and UTMRL base address registers */
1347 dwc_ufs_write_reg(UFS_UTRLBA_OFF,
1348 lower_32_bits((uintptr_t)hba->utrl_base_addr));
1349 dwc_ufs_write_reg(UFS_UTRLBAU_OFF,
1350 upper_32_bits((uintptr_t)hba->utrl_base_addr));
1351
1352 dwc_ufs_write_reg(UFS_UTMRLBA_OFF,
1353 lower_32_bits((uintptr_t)hba->utmrl_base_addr));
1354 dwc_ufs_write_reg(UFS_UTMRLBAU_OFF,
1355 upper_32_bits((uintptr_t)hba->utmrl_base_addr));
1356 }
1357
create_prdt_part(struct cmd_param * param,uint32_t buf_size,uint8_t free_slot)1358 static void create_prdt_part(struct cmd_param *param, uint32_t buf_size, uint8_t free_slot)
1359 {
1360 int i;
1361 uint32_t size = param->size;
1362 struct dwc_ufs_prd *prdt = NULL;
1363
1364 get_local_dwc_host();
1365
1366 prdt = dwc_host->lrb[free_slot].prdt;
1367 /* Fill PRD Table Info */
1368 for (i = 0; (size); i++) {
1369 prdt[i].base_addr = (lower_32_bits(param->addr + (i * buf_size)));
1370 prdt[i].upper_addr = (upper_32_bits(param->addr + (i * buf_size)));
1371 prdt[i].reserved1 = 0x0;
1372 prdt[i].size = to_littleendian32(((buf_size < size) ? buf_size : size) - 1);
1373 size -= (buf_size < size) ? buf_size : size;
1374 }
1375 }
1376
create_cmd_part(uint32_t opcode,uint8_t upiu_flags,struct cmd_param * param,uint8_t free_slot)1377 static void create_cmd_part(uint32_t opcode, uint8_t upiu_flags,
1378 struct cmd_param *param, uint8_t free_slot)
1379 {
1380 struct dwc_ufs_cmd_upiu *cmd_upiu_ptr = NULL;
1381 struct dwc_ufs_ucd *ucd = NULL;
1382
1383 get_local_dwc_host();
1384
1385 ucd = dwc_host->ucdl_base_addr;
1386 ucd += free_slot;
1387 cmd_upiu_ptr = (struct dwc_ufs_cmd_upiu *)ucd->cmd_upiu;
1388
1389 cmd_upiu_ptr->trans_type = 0x01;
1390 cmd_upiu_ptr->flags = upiu_flags;
1391 cmd_upiu_ptr->lun = dwc_host->active_lun;
1392 cmd_upiu_ptr->task_tag = free_slot;
1393 cmd_upiu_ptr->cmd_set_type = 0x0;
1394 cmd_upiu_ptr->reserved_1_0 = 0x0;
1395 cmd_upiu_ptr->reserved_1_1 = 0x0;
1396 cmd_upiu_ptr->reserved_1_2 = 0x0;
1397 cmd_upiu_ptr->tot_ehs_len = 0x0;
1398 cmd_upiu_ptr->reserved_2 = 0x0;
1399 cmd_upiu_ptr->data_seg_len = 0x0;
1400 cmd_upiu_ptr->exp_data_xfer_len = to_bigendian32(param->size);
1401
1402 if (opcode == UFS_OP_READ_10 || opcode == UFS_OP_WRITE_10 ||
1403 opcode == UFS_OP_SYNCHRONIZE_CACHE_10) {
1404 get_cmnd(opcode, (uint32_t)(param->src / LOGICAL_BLK_SIZE),
1405 (param->size / LOGICAL_BLK_SIZE), cmd_upiu_ptr->cdb);
1406 } else {
1407 get_cmnd(opcode, 0, param->size, cmd_upiu_ptr->cdb);
1408 }
1409
1410 /* In Power Management Command: START STOP UNIT, the LUN is fixed
1411 to 0x50 or 0xD0 for W-LUN */
1412 if (opcode == UFS_OP_START_STOP_UNIT && ((cmd_upiu_ptr->cdb[0x4] & 0xF0) != 0))
1413 cmd_upiu_ptr->lun = 0xD0;
1414 }
1415
1416 /***************************************************************
1417 * create_cmd_upiu
1418 * Description: Fills the Command UPIU memory,
1419 * updates prdt entries
1420 * free_slot:free slot in memory, 0~31 in UTRL, 0~7 in UTMRL
1421 *
1422 ***************************************************************/
create_cmd_upiu(uint32_t opcode,enum dma_data_direction direction,struct cmd_param * param,uint8_t free_slot)1423 static int create_cmd_upiu(uint32_t opcode, enum dma_data_direction direction,
1424 struct cmd_param *param, uint8_t free_slot)
1425 {
1426 uint32_t data_direction;
1427 uint8_t upiu_flags;
1428 struct dwc_ufs_utrd *utrd = NULL;
1429 struct dwc_ufs_ucd *ucd = NULL;
1430 uint32_t buf_size = PRDT_BUFFER_SIZE;
1431
1432 get_local_dwc_host();
1433
1434 if (opcode == UFS_OP_READ_10 || opcode == UFS_OP_WRITE_10 ||
1435 opcode == UFS_OP_SYNCHRONIZE_CACHE_10) {
1436 if ((param->src % LOGICAL_BLK_SIZE) || (param->size % LOGICAL_BLK_SIZE)) {
1437 printf("!!!!!access ufs is not round with ufs blocksize,"
1438 "src is 0x%llx, size is 0x%x, blocksize is 0x%x\n",
1439 param->src, param->size, LOGICAL_BLK_SIZE);
1440 return UFS_SOFTWARE_ERROR;
1441 }
1442 }
1443 if (opcode == UFS_OP_SECURITY_PROTOCOL_IN || opcode == UFS_OP_SECURITY_PROTOCOL_OUT)
1444 buf_size = RPMB_FRAME_SIZE;
1445
1446 /* Get the ucd of the free slot */
1447 ucd = dwc_host->ucdl_base_addr;
1448 ucd += free_slot;
1449 /* Get the xfer descriptor of the free slot */
1450 utrd = dwc_host->utrl_base_addr;
1451 utrd += free_slot;
1452
1453 if (direction == DMA_FROM_DEVICE) {
1454 data_direction = UTP_DEVICE_TO_HOST;
1455 upiu_flags = UPIU_CMD_FLAGS_READ;
1456 } else if (direction == DMA_TO_DEVICE) {
1457 data_direction = UTP_HOST_TO_DEVICE;
1458 upiu_flags = UPIU_CMD_FLAGS_WRITE;
1459 } else {
1460 data_direction = UTP_NO_DATA_TRANSFER;
1461 upiu_flags = UPIU_CMD_FLAGS_NONE;
1462 }
1463
1464 /* Update cmd_type, flags and response upiu length */
1465 utrd->ct_and_flags = (uint8_t)(data_direction | UTP_UFS_STORAGE_COMMAND);
1466 utrd->resp_upiu_length = to_littleendian16((uint16_t)
1467 (sizeof(struct dwc_ufs_resp_upiu) >> UFS_DWORD_SHIFT));
1468 utrd->prdt_length = to_littleendian16((uint16_t)((param->size & (buf_size - 1)) ?
1469 ((param->size / buf_size) + 1) : (param->size / buf_size)));
1470 utrd->ocs = 0xf;
1471
1472 create_cmd_part(opcode, upiu_flags, param, free_slot);
1473 create_prdt_part(param, buf_size, free_slot);
1474
1475 /* occupy this slot */
1476 dwc_host->outstanding_xfer_reqs |= BIT(free_slot);
1477
1478 return UFS_SUCCESS;
1479 }
1480
1481 /****************************************************************
1482 * ufs_soft_init
1483 * Description: alloc memory for dwc_host
1484 *
1485 ****************************************************************/
ufs_soft_init(void)1486 static int ufs_soft_init(void)
1487 {
1488 int ret;
1489
1490 get_local_dwc_host();
1491
1492 memset((void *)dwc_host, 0, sizeof(struct dwc_ufs_hba));
1493
1494 /* Read host Controller Capabilities */
1495 dwc_ufshcd_read_caps(dwc_host);
1496
1497 /* Allocate memory required to interface with host */
1498 ret = dwc_ufshcd_alloc_interface_memory(dwc_host);
1499 if (ret != UFS_OK) {
1500 printf("%s: allocating required memory error\n", __func__);
1501 return ret;
1502 }
1503
1504 /* Configure the HC memory with required information and the LRB */
1505 dwc_ufshcd_configure_interface_memory(dwc_host);
1506
1507 return UFS_OK;
1508 }
1509
ufs_config_init(void)1510 static void ufs_config_init(void)
1511 {
1512 int i;
1513 uint32_t value;
1514
1515 get_local_dwc_host();
1516
1517 /* Unipro DL_AFC0CreditThreshold */
1518 send_uic_command(DME_SET, 0x20440000, 0, 0x0);
1519 /* Unipro DL_TC0OutAckThreshold */
1520 send_uic_command(DME_SET, 0x20450000, 0, 0x0);
1521 /* Unipro DL_TC0TXFCThreshold */
1522 send_uic_command(DME_SET, 0x20400000, 0, 0x9);
1523
1524 #ifdef UFS_USE_HISI_MPHY_TC
1525 #if defined(COMBO_PHY_V120)
1526 /* H8's workaround */
1527 /* PA_TActivate */
1528 send_uic_command(DME_SET, 0x15a80000, 0x0, 0xa);
1529 /* RX H8_TIMEOUT_VAL, Lane 0 */
1530 send_uic_command(DME_SET, 0x000a0004, 0x0, 0x1E);
1531 /* RX H8_TIMEOUT_VAL, Lane 1 */
1532 send_uic_command(DME_SET, 0x000a0005, 0x0, 0x1E);
1533 #endif
1534
1535 /* If the PLL is slow and needs more than 10 us
1536 * then this field can be used to specify the wait period unit. If
1537 * the value of this field */
1538 value = uic_cmd_read(DME_GET, 0xd0a00000); /* VS_DebugSaveConfigTime */
1539 value &= (uint32_t)(~(0x7 << 2));/* bit[4:2] = 0 */
1540 value |= 0x3 << 2; /* bit[4:2] = 3 */
1541 /* enlarge for default's 10us to 31250ns,
1542 can make rateA->B change smoothly */
1543 send_uic_command(DME_SET, 0xd0a00000, 0x0, value);
1544 #endif
1545
1546 /* the ufs register will be reset, so set the ufs register always*/
1547 dwc_ufshcd_initialize_hba_desc_pointers(dwc_host);
1548 for (i = 0; i < UNIT_DESCS_COUNT; i++)
1549 dwc_host->lu_request_sense_sent[i] = 0;
1550
1551 dwc_ufs_write_reg(UFS_UTRLRSR_OFF, UFS_UTP_RUN_BIT);
1552 dwc_ufs_write_reg(UFS_UTMRLRSR_OFF, UFS_UTP_RUN_BIT);
1553 }
1554
1555 /***************************************************************
1556 * read_nop_rsp
1557 * Description: The function reads and validates the response
1558 * received for NOP command
1559 *
1560 ***************************************************************/
read_nop_rsp(uint8_t free_slot)1561 static int read_nop_rsp(uint8_t free_slot)
1562 {
1563 struct dwc_ufs_nop_resp_upiu *resp_upiu = NULL;
1564 struct dwc_ufs_utrd *utrd = NULL;
1565
1566 get_local_dwc_host();
1567
1568 resp_upiu = (struct dwc_ufs_nop_resp_upiu *)dwc_host->lrb[free_slot].resp_upiu;
1569 utrd = dwc_host->lrb[free_slot].utrd;
1570
1571 if (utrd->ocs != UFS_SUCCESS) {
1572 printf("send nop out ocs err\n");
1573 ufs_reg_dump();
1574 return -((utrd->ocs & 0xf) + RET_UTRD_OCS_ERROR_OFF);
1575 }
1576
1577 if ((resp_upiu->trans_type & 0x3F) != NOP_TRANS_TYPE) {
1578 printf("invalid nop in trans_type 0x%x\n", (resp_upiu->trans_type & 0x3F));
1579 ufs_reg_dump();
1580 return UFS_INVALID_NOP_IN;
1581 }
1582
1583 if (resp_upiu->response != UFS_SUCCESS) {
1584 printf("nop in response error, resp = 0x%x\n", resp_upiu->response);
1585 return UFS_NOP_RESP_FAIL;
1586 }
1587
1588 return UFS_SUCCESS;
1589 }
1590
1591 /***************************************************************
1592 * wait_for_cmd_completion
1593 * Description: Sets the DoorBell Register and waits for the
1594 * Doorbell to Clear. Returns Zero on Success or
1595 * error number on Failure
1596 *
1597 ***************************************************************/
wait_for_cmd_completion(uint32_t slot_mask)1598 int wait_for_cmd_completion(uint32_t slot_mask)
1599 {
1600 int retry = 5000; /* 5000ms timeout */
1601
1602 get_local_dwc_host();
1603
1604 flush_dcache_all();
1605 /* Set the doorbell for processing the request */
1606 dwc_ufs_write_reg(UFS_UTRLDBR_OFF, slot_mask);
1607
1608 /* Wait for the DoorBell to clear */
1609 for (;;) {
1610 if ((dwc_ufs_read_reg(UFS_UTRLDBR_OFF) & slot_mask) == 0) {
1611 break;
1612 }
1613 if (--retry == 0) {
1614 printf("UTRL DoorBell Not Cleared and Timed Out, "
1615 "DoorBell is 0x%x, slot_mask is 0x%x\n",
1616 dwc_ufs_read_reg(UFS_UTRLDBR_OFF), slot_mask);
1617 ufs_reg_dump();
1618
1619 dwc_ufs_write_reg(UFS_UTRLCLR_OFF, 0);
1620 dwc_host->outstanding_xfer_reqs = 0;
1621
1622 return UFS_UTRD_DOORBELL_TIMEOUT;
1623 }
1624 ufs_waitms(1);
1625 }
1626 invalidate_dcache_all();
1627 return UFS_SUCCESS;
1628 }
1629
1630 /***************************************************************
1631 * create_nop_out_upiu
1632 * Description: Fills the UPIU memory for NOP OUT command
1633 *
1634 ***************************************************************/
create_nop_out_upiu(uint8_t free_slot)1635 static void create_nop_out_upiu(uint8_t free_slot)
1636 {
1637 struct dwc_ufs_nop_req_upiu *cmd_upiu_ptr = NULL;
1638 struct dwc_ufs_nop_resp_upiu *resp_upiu = NULL;
1639 int i;
1640 struct dwc_ufs_utrd *utrd = NULL;
1641
1642 get_local_dwc_host();
1643
1644 cmd_upiu_ptr = (struct dwc_ufs_nop_req_upiu *)dwc_host->lrb[free_slot].cmd_upiu;
1645
1646 utrd = dwc_host->lrb[free_slot].utrd;
1647
1648 utrd->ct_and_flags = (uint8_t)(UTP_NO_DATA_TRANSFER | UTP_UFS_STORAGE_COMMAND);
1649 utrd->resp_upiu_length = to_littleendian16((uint16_t)
1650 (sizeof(struct dwc_ufs_nop_resp_upiu) >> UFS_DWORD_SHIFT));
1651 utrd->prdt_length = 0;
1652 utrd->ocs = 0xf;
1653
1654 cmd_upiu_ptr->trans_type = 0x00;
1655 cmd_upiu_ptr->flags = 0x00;
1656 cmd_upiu_ptr->reserved_1 = 0x00;
1657 cmd_upiu_ptr->task_tag = free_slot;
1658 cmd_upiu_ptr->reserved_2 = 0x0;
1659 cmd_upiu_ptr->tot_ehs_len = 0x00;
1660 cmd_upiu_ptr->reserved_3 = 0x00;
1661 cmd_upiu_ptr->data_seg_len = 0x00;
1662 for (i = 0; i < 20; i++) /* reserved: 20 bytes */
1663 cmd_upiu_ptr->reserved_4[i] = 0x00;
1664
1665 resp_upiu = (struct dwc_ufs_nop_resp_upiu *)dwc_host->lrb[free_slot].resp_upiu;
1666 memset((void *)resp_upiu, 0, sizeof(struct dwc_ufs_nop_resp_upiu));
1667 }
1668
send_nop_out_cmd(void)1669 static int send_nop_out_cmd(void)
1670 {
1671 int ret;
1672 int i;
1673 uint8_t free_slot;
1674
1675 get_local_dwc_host();
1676 for (i = 0; i < 5; i++) { /* retry 5 times */
1677 free_slot = dwc_ufshcd_get_xfer_req_free_slot(dwc_host);
1678 if (free_slot == BAD_SLOT)
1679 return UFS_ERR;
1680
1681 create_nop_out_upiu(free_slot);
1682 ret = wait_for_cmd_completion(BIT(free_slot));
1683 if (ret == UFS_SUCCESS)
1684 ret = read_nop_rsp(free_slot);
1685
1686 if (ret == UFS_SUCCESS)
1687 break;
1688
1689 printf("nop out nop in fail, ret = %d, retry = %d\n", ret, i);
1690 ufs_waitms(10); /* delay 10ms */
1691 }
1692
1693 return ret;
1694 }
1695
1696 /***************************************************************
1697 * handle_query_response
1698 * Description: The functon does the following
1699 * 1. validates the query command's response received
1700 * 2. updates the ret argument with query data
1701 * 3. returns the status
1702 *
1703 ***************************************************************/
handle_query_response(uint8_t * ret,uint8_t free_slot)1704 static int handle_query_response(uint8_t *ret, uint8_t free_slot)
1705 {
1706 struct dwc_ufs_query_upiu *resp_upiu = NULL;
1707
1708 get_local_dwc_host();
1709
1710 resp_upiu = (struct dwc_ufs_query_upiu *)dwc_host->lrb[free_slot].resp_upiu;
1711
1712 /* Update the return value */
1713 if (ret != NULL) {
1714 ret[0] = resp_upiu->tsf[11]; /* val 0: tsf 11 */
1715 ret[1] = resp_upiu->tsf[10]; /* val 1: tsf 10 */
1716 ret[2] = resp_upiu->tsf[9]; /* val 2: tsf 9 */
1717 ret[3] = resp_upiu->tsf[8]; /* val 3: tsf 8 */
1718 }
1719
1720 if (resp_upiu->query_resp == UFS_SUCCESS)
1721 return UFS_SUCCESS;
1722
1723 printf("Query Response error: 0x%x\n", resp_upiu->query_resp);
1724 return -(resp_upiu->query_resp);
1725 }
1726
1727 /***************************************************************
1728 * create_query_upiu
1729 * Description: Populates the UPIU memory for all query Operations
1730 *
1731 ***************************************************************/
create_query_upiu(uint8_t query_func,struct query_param * param,const uint8_t * val,uint8_t free_slot)1732 static void create_query_upiu(uint8_t query_func, struct query_param *param,
1733 const uint8_t *val, uint8_t free_slot)
1734 {
1735 struct dwc_ufs_query_upiu *cmd_upiu_ptr = NULL;
1736 struct dwc_ufs_utrd *utrd = NULL;
1737 int i;
1738
1739 get_local_dwc_host();
1740 cmd_upiu_ptr = (struct dwc_ufs_query_upiu *)dwc_host->lrb[free_slot].cmd_upiu;
1741
1742 utrd = dwc_host->lrb[free_slot].utrd;
1743
1744 /* UTRD Descriptor Programming for processing command */
1745 utrd->ct_and_flags = (uint8_t)
1746 (UTP_NO_DATA_TRANSFER | UTP_UFS_STORAGE_COMMAND);
1747 utrd->resp_upiu_length = to_littleendian16((uint16_t)
1748 (sizeof(struct dwc_ufs_query_upiu) >> UFS_DWORD_SHIFT));
1749 utrd->prdt_length = 0;
1750
1751 /* Command Descriptor Programming */
1752 cmd_upiu_ptr->trans_type = 0x16;
1753 cmd_upiu_ptr->flags = UPIU_CMD_FLAGS_NONE;
1754 cmd_upiu_ptr->reserved_1 = 0x00;
1755 cmd_upiu_ptr->task_tag = free_slot;
1756 cmd_upiu_ptr->reserved_2 = 0x00;
1757 cmd_upiu_ptr->query_func = query_func;
1758 cmd_upiu_ptr->query_resp = 0x00;
1759 cmd_upiu_ptr->reserved_3 = 0x00;
1760 cmd_upiu_ptr->tot_ehs_len = 0x00;
1761 cmd_upiu_ptr->data_seg_len = 0x00;
1762
1763 for (i = 0; i < 16; i++) /* clear 16 byte */
1764 cmd_upiu_ptr->tsf[i] = 0x0;
1765 cmd_upiu_ptr->tsf[0] = param->opcode; /* 0: opcode */
1766 cmd_upiu_ptr->tsf[1] = param->idn; /* 1: idn */
1767 cmd_upiu_ptr->tsf[2] = param->index; /* 2: index */
1768 cmd_upiu_ptr->tsf[3] = param->selector; /* 3: selector */
1769 /* Value/Flag Updation */
1770 cmd_upiu_ptr->tsf[8] = val[3]; /* 8: val 3 */
1771 cmd_upiu_ptr->tsf[9] = val[2]; /* 9: val 2 */
1772 cmd_upiu_ptr->tsf[10] = val[1]; /* 10: val 1 */
1773 cmd_upiu_ptr->tsf[11] = val[0]; /* 11: val 0 */
1774 cmd_upiu_ptr->reserved_5 = 0x0;
1775 }
1776
1777 /***************************************************************
1778 * send_scsi_cmd
1779 * Description: function creates UPIU for scsi commands sends it
1780 * to the device by setting the DoorBell.
1781 *
1782 ****************************************************************/
send_scsi_cmd(uint32_t opcode,enum dma_data_direction direction,uint64_t buf_addr,uint64_t rel_addr,uint32_t size)1783 static int send_scsi_cmd(uint32_t opcode, enum dma_data_direction direction,
1784 uint64_t buf_addr, uint64_t rel_addr, uint32_t size)
1785 {
1786 int ret;
1787 uint8_t free_slot;
1788 struct cmd_param param = {buf_addr, rel_addr, size};
1789
1790 get_local_dwc_host();
1791 if (lower_32_bits(buf_addr) % 0x4) {
1792 printf("fail! buf_addr:0x%llx is not round to D-Words\n", buf_addr);
1793 return UFS_SOFTWARE_ERROR;
1794 }
1795 if (size % 0x4) {
1796 printf("fail! size:0x%x is not round to D-Words\n", size);
1797 return UFS_SOFTWARE_ERROR;
1798 }
1799 if (size / PRDT_BUFFER_SIZE > DWC_UFSHCD_MAX_PRD_SIZE) {
1800 printf("fail! size:0x%x is bigger than PRDT alloc\n", size);
1801 return UFS_SOFTWARE_ERROR;
1802 }
1803
1804 free_slot = dwc_ufshcd_get_xfer_req_free_slot(dwc_host);
1805 if (free_slot == BAD_SLOT)
1806 return UFS_ERR;
1807
1808 ret = create_cmd_upiu(opcode, direction, ¶m, free_slot);
1809 if (ret != UFS_SUCCESS) {
1810 printf("create_cmd_upiu fail! ret %d\n", ret);
1811 return ret;
1812 }
1813
1814 ret = wait_for_cmd_completion(BIT(free_slot));
1815 return ret;
1816 }
1817
handle_response_status(struct dwc_ufs_resp_upiu * resp_upiu)1818 static int handle_response_status(struct dwc_ufs_resp_upiu *resp_upiu)
1819 {
1820 uint8_t status;
1821 int ret;
1822
1823 status = resp_upiu->status;
1824 if (status == SAM_STAT_GOOD) {
1825 /* do nothing */
1826 ret = 0;
1827 } else if (status == SAM_STAT_CHECK_CONDITION) {
1828 /* 0x20 is added to sense key to return
1829 * unique error code */
1830 ret = -(RET_SENSE_KEY_OFF +
1831 (resp_upiu->sense_data[2] & 0xf)); /* byte 2: sense key */
1832 /* because other slot to check, so not
1833 * return here */
1834 printf("The sense key is 0x%x, ASC is 0x%x, ASCQ is 0x%x\n",
1835 ((uint8_t *)resp_upiu)[SENSE_KEY_INDEX] & 0xf,
1836 ((uint8_t *)resp_upiu)[SENSE_KEY_INDEX + 0xa],
1837 ((uint8_t *)resp_upiu)[SENSE_KEY_INDEX + 0xb]);
1838 } else {
1839 switch (status) {
1840 case SAM_STAT_CONDITION_MET:
1841 ret = RESP_STAT_CONDITION_MET;
1842 break;
1843 case SAM_STAT_BUSY:
1844 ret = RESP_STAT_BUSY;
1845 break;
1846 case SAM_STAT_RESERVATION_CONFLICT:
1847 ret = RESP_STAT_RESERVATION_CONFLICT;
1848 break;
1849 case SAM_STAT_TASK_SET_FULL:
1850 ret = RESP_STAT_TASK_SET_FULL;
1851 break;
1852 case SAM_STAT_ACA_ACTIVE:
1853 ret = RESP_STAT_ACA_ACTIVE;
1854 break;
1855 case SAM_STAT_TASK_ABORTED:
1856 ret = RESP_STAT_TASK_ABORTED;
1857 break;
1858 default:
1859 ret = RESP_STAT_UNKNOWN;
1860 }
1861 }
1862
1863 return ret;
1864 }
1865
1866 /***************************************************************
1867 * handle_scsi_completion
1868 * Description: The functon validates the SCSI command's
1869 * response received
1870 *
1871 ***************************************************************/
handle_scsi_completion(void)1872 static int handle_scsi_completion(void)
1873 {
1874 struct dwc_ufs_resp_upiu *resp_upiu = NULL;
1875 struct dwc_ufs_utrd *utrd = NULL;
1876 uint8_t slot_index;
1877 int i;
1878 int ret = 0;
1879
1880 get_local_dwc_host();
1881 for (i = 0; i < dwc_host->nutrs; i++) {
1882 slot_index = (uint8_t)i;
1883 /* the outstanding is set on, so dump the response,
1884 and then clear the bit */
1885 if (dwc_host->outstanding_xfer_reqs & BIT(slot_index)) {
1886 resp_upiu = dwc_host->lrb[slot_index].resp_upiu;
1887 utrd = dwc_host->lrb[slot_index].utrd;
1888
1889 /* finish the requset here */
1890 dwc_host->outstanding_xfer_reqs ^= BIT(slot_index);
1891
1892 if (utrd->ocs == UFS_SUCCESS) {
1893 ret = handle_response_status(resp_upiu);
1894 } else {
1895 ret = -((utrd->ocs & 0xf) + RET_UTRD_OCS_ERROR_OFF);
1896 ufs_reg_dump();
1897 }
1898 }
1899 }
1900
1901 return ret;
1902 }
1903
do_scsi_cmd(uint32_t opcode,enum dma_data_direction direction,uint64_t buf_addr,uint64_t rel_addr,uint32_t size)1904 static int do_scsi_cmd(uint32_t opcode, enum dma_data_direction direction,
1905 uint64_t buf_addr, uint64_t rel_addr, uint32_t size)
1906 {
1907 int ret;
1908
1909 ret = send_scsi_cmd(opcode, direction, buf_addr, rel_addr, size);
1910 if (ret != UFS_SUCCESS) {
1911 printf("send scsi cmd[0x%x] error: %d\n", opcode, ret);
1912 return ret;
1913 }
1914
1915 ret = handle_scsi_completion();
1916 if (ret != UFS_SUCCESS) {
1917 printf("handle scsi cmd[0x%x] completion error: %d\n",
1918 opcode, ret);
1919 return ret;
1920 }
1921 return ret;
1922 }
1923
1924 /***************************************************************
1925 * create_desc_upiu
1926 * Description: The function does a simple memcpy of the req_upiu
1927 * content passed to UPIU memory for Read/Write
1928 * descriptor Operation
1929 *
1930 ***************************************************************/
create_desc_upiu(const void * req_upiu,uint8_t free_slot)1931 static void create_desc_upiu(const void *req_upiu, uint8_t free_slot)
1932 {
1933 unsigned int len;
1934
1935 get_local_dwc_host();
1936
1937 len = (unsigned int)(sizeof(struct dwc_ufs_query_upiu) +
1938 to_bigendian16(((struct dwc_ufs_query_upiu *)req_upiu)->data_seg_len));
1939
1940 if (dwc_host->lrb[free_slot].cmd_upiu == req_upiu)
1941 return;
1942 memcpy(dwc_host->lrb[free_slot].cmd_upiu, req_upiu, len);
1943 }
1944
1945 /***************************************************************
1946 * write_descriptor
1947 * Description: The functon populates the request upiu structure
1948 * with upiu info passed in 1st argument
1949 *
1950 ***************************************************************/
write_descriptor(const void * req_upiu)1951 int write_descriptor(const void *req_upiu)
1952 {
1953 int ret;
1954 struct dwc_ufs_utrd *utrd = NULL;
1955 uint8_t free_slot;
1956
1957 get_local_dwc_host();
1958
1959 free_slot = dwc_ufshcd_get_xfer_req_free_slot(dwc_host);
1960 if (free_slot == BAD_SLOT)
1961 return UFS_ERR;
1962 utrd = dwc_host->lrb[free_slot].utrd;
1963
1964 /* UTRD Descriptor Programming for processing command */
1965 utrd->ct_and_flags = (uint8_t)
1966 (UTP_NO_DATA_TRANSFER | UTP_UFS_STORAGE_COMMAND);
1967 utrd->resp_upiu_length = to_littleendian16((uint16_t)
1968 (sizeof(struct dwc_ufs_query_upiu) >> UFS_DWORD_SHIFT));
1969 utrd->prdt_length = 0;
1970
1971 create_desc_upiu(req_upiu, free_slot);
1972
1973 ret = wait_for_cmd_completion(BIT(free_slot));
1974 if (ret != UFS_SUCCESS) {
1975 return ret;
1976 }
1977
1978 ret = handle_query_response(NULL, free_slot);
1979
1980 return ret;
1981 }
1982
1983 /***************************************************************
1984 * read_attribute
1985 * Description: The functon sends the query command to read an
1986 * attribute and updates the ret_value with the
1987 * content of the attribute
1988 *
1989 ***************************************************************/
read_attribute(enum attr_id idn,uint8_t index,uint8_t selector,uint32_t * ret_value)1990 int read_attribute(enum attr_id idn, uint8_t index, uint8_t selector, uint32_t *ret_value)
1991 {
1992 int ret;
1993 uint8_t free_slot;
1994 struct query_param param = {READ_ATTR_OPCODE, idn, index, selector};
1995
1996 get_local_dwc_host();
1997 free_slot = dwc_ufshcd_get_xfer_req_free_slot(dwc_host);
1998 if (free_slot == BAD_SLOT)
1999 return UFS_ERR;
2000 *ret_value = 0;
2001
2002 create_query_upiu(STANDARD_RD_REQ, ¶m, (uint8_t *)ret_value, free_slot);
2003 ret = wait_for_cmd_completion(BIT(free_slot));
2004 if (ret != UFS_SUCCESS)
2005 return ret;
2006
2007 ret = handle_query_response((uint8_t *)ret_value, free_slot);
2008 return ret;
2009 }
2010
2011 /***************************************************************
2012 * write_attribute
2013 * Description: The functon sends the query command to write an
2014 * attribute with the value passed as second argument
2015 *
2016 ***************************************************************/
write_attribute(enum attr_id idn,uint8_t index,uint8_t selector,uint32_t * value)2017 int write_attribute(enum attr_id idn, uint8_t index, uint8_t selector, uint32_t *value)
2018 {
2019 int ret;
2020 uint8_t free_slot;
2021 struct query_param param = {WRITE_ATTR_OPCODE, idn, index, selector};
2022
2023 get_local_dwc_host();
2024 free_slot = dwc_ufshcd_get_xfer_req_free_slot(dwc_host);
2025 if (free_slot == BAD_SLOT)
2026 return UFS_ERR;
2027
2028 create_query_upiu(STANDARD_WR_REQ, ¶m, (uint8_t *)value, free_slot);
2029 ret = wait_for_cmd_completion(BIT(free_slot));
2030 if (ret != UFS_SUCCESS) {
2031 return ret;
2032 }
2033
2034 ret = handle_query_response((uint8_t *)value, free_slot);
2035 return ret;
2036 }
2037
update_lu_memory_type(struct partition_desc_table * pdt,int index,uint32_t * p_max_alloc_unit,uint32_t * numerator)2038 static int update_lu_memory_type(struct partition_desc_table *pdt, int index,
2039 uint32_t *p_max_alloc_unit, uint32_t *numerator)
2040 {
2041 uint16_t cap_adj_fac = 0;
2042 const uint16_t fac_div = 256;
2043
2044 if ((BIT(pdt->partition_desc_ptr[index]->memory_type) &
2045 pdt->w_supported_memory_types) == 0) {
2046 printf("device not support memory type: %d\n",
2047 pdt->partition_desc_ptr[index]->memory_type);
2048 return -1;
2049 }
2050
2051 switch (pdt->partition_desc_ptr[index]->memory_type) {
2052 case 0x0:
2053 cap_adj_fac = 1;
2054 p_max_alloc_unit = NULL;
2055 break;
2056 case 0x1:
2057 cap_adj_fac = pdt->w_system_code_cap_adj_fac / fac_div;
2058 p_max_alloc_unit = &(pdt->d_system_code_max_alloc_u);
2059 break;
2060 case 0x2:
2061 cap_adj_fac = pdt->w_non_persist_cap_adj_fac / fac_div;
2062 p_max_alloc_unit = &(pdt->d_non_persist_max_alloc_u);
2063 break;
2064 case 0x3:
2065 cap_adj_fac = pdt->w_enhanced1_cap_adj_fac / fac_div;
2066 p_max_alloc_unit = &(pdt->d_enhanced1_max_alloc_u);
2067 break;
2068 case 0x4:
2069 cap_adj_fac = pdt->w_enhanced2_cap_adj_fac / fac_div;
2070 p_max_alloc_unit = &(pdt->d_enhanced2_max_alloc_u);
2071 break;
2072 default:
2073 printf("unknown memory type\n");
2074 return -1;
2075 }
2076 if (pdt->partition_desc_ptr[index]->lu_capacity * cap_adj_fac >= 0x200000) {
2077 printf("input lu_capacity set too large\n");
2078 return -1;
2079 }
2080 *numerator = (pdt->partition_desc_ptr[index]->lu_capacity) * 0x800 * cap_adj_fac;
2081 return 0;
2082 }
2083
2084 /***************************************************************
2085 * update_lu_capacity_info
2086 * Updates the dNumAllocUnits information for the Logic Unit
2087 * indexed by index. In addition, this also tracks the number
2088 * of LUs that will be provisioned in the device.
2089 *
2090 ***************************************************************/
update_lu_capacity_info(struct partition_desc_table * pdt)2091 static int update_lu_capacity_info(struct partition_desc_table *pdt)
2092 {
2093 uint32_t numerator;
2094 const uint32_t denominator = (pdt->b_allocation_unit_size) * (pdt->d_segment_size);
2095 uint32_t alloced_units = 0;
2096 uint32_t *p_max_alloc_unit = NULL;
2097 int max_cap_lu = -1;
2098 int i;
2099
2100 /* Initialize the LUN tracker to zero */
2101 pdt->b_number_lu = 0;
2102
2103 for (i = 0; i < UNIT_DESCS_COUNT; i++) {
2104 if (pdt->partition_desc_ptr[i] == NULL)
2105 continue;
2106 if (pdt->partition_desc_ptr[i]->lu_capacity == UFS_MAX_LU_CAP) {
2107 if (max_cap_lu != -1) {
2108 printf("more than one lu set UFS_MAX_LU_CAP\n");
2109 return -1;
2110 }
2111 max_cap_lu = i;
2112 continue;
2113 }
2114 if (update_lu_memory_type(pdt, i, p_max_alloc_unit, &numerator))
2115 return -1;
2116 pdt->partition_desc_ptr[i]->num_alloc_units =
2117 (numerator + denominator - 1) / denominator;
2118 ufs_pr_dbg("lun %d-NumAllocUnits: 0x%x\n", i,
2119 pdt->partition_desc_ptr[i]->num_alloc_units);
2120 if (p_max_alloc_unit != NULL) {
2121 if (pdt->partition_desc_ptr[i]->num_alloc_units > *p_max_alloc_unit) {
2122 printf("alloc units more than this type 0x%x\n",
2123 pdt->partition_desc_ptr[i]->memory_type);
2124 return -1;
2125 }
2126 *p_max_alloc_unit -= pdt->partition_desc_ptr[i]->num_alloc_units;
2127 }
2128 alloced_units += pdt->partition_desc_ptr[i]->num_alloc_units;
2129 pdt->b_number_lu += 1;
2130 }
2131
2132 if (max_cap_lu != -1) {
2133 numerator = lower_32_bits(pdt->q_total_raw_device_capacity);
2134 pdt->partition_desc_ptr[max_cap_lu]->num_alloc_units =
2135 numerator / denominator - alloced_units;
2136 pdt->b_number_lu += 1;
2137 }
2138
2139 return 0;
2140 }
2141
compair_unit_part(struct partition_desc_table * pdt)2142 static int compair_unit_part(struct partition_desc_table *pdt)
2143 {
2144 struct partition_desc *desc = NULL;
2145 struct ufs_unit_desc_configuration_param unit;
2146 int i, ret;
2147
2148 for (i = 0; i < UNIT_DESCS_COUNT; i++) {
2149 desc = pdt->partition_desc_ptr[i];
2150 unit = g_ufs_desc.conf_desc.unit_desc_conf_param[i];
2151 ret = 0x10 * (i + 1);
2152 if (desc == NULL) {
2153 /* the Lun should be disabled */
2154 if (unit.b_lu_enable != 0x0)
2155 return ret;
2156 continue;
2157 }
2158 if (unit.b_lu_enable != 0x1)
2159 return ret;
2160 if (unit.b_boot_lun_id != desc->boot_lun_id)
2161 return ret + 0x1;
2162 if (unit.b_lu_write_protect != desc->write_protect)
2163 return ret + 0x2;
2164 if (unit.b_memory_type != desc->memory_type)
2165 return ret + 0x3;
2166 if (to_bigendian32(unit.d_num_alloc_units) != desc->num_alloc_units)
2167 return ret + 0x4;
2168 if (unit.b_data_reliability != desc->data_reliability)
2169 return ret + 0x8;
2170 if (unit.b_logical_block_size != desc->block_size)
2171 return ret + 0x9;
2172 if (unit.b_provisioning_type != desc->prov_type)
2173 return ret + 0xA;
2174 if (to_bigendian16(unit.w_context_capabilities) != desc->context_capabilities)
2175 return ret + 0xB;
2176 }
2177 return 0;
2178 }
2179
compair_conf_desp(struct partition_desc_table * pdt)2180 static int compair_conf_desp(struct partition_desc_table *pdt)
2181 {
2182 struct ufs_dev_desc_configuration_param dev;
2183
2184 dev = g_ufs_desc.conf_desc.dev_desc_conf_param;
2185
2186 if (pdt->p_conf_header->b_boot_enable != dev.b_boot_enable)
2187 return 0x3;
2188 if (pdt->p_conf_header->b_descr_access_en != dev.b_descr_access_en)
2189 return 0x4;
2190 if (pdt->p_conf_header->b_init_power_mode != dev.b_init_power_mode)
2191 return 0x5;
2192 if (pdt->p_conf_header->b_high_priority_lun != dev.b_high_priority_lun)
2193 return 0x6;
2194 if (pdt->p_conf_header->b_secure_removal_type != dev.b_secure_removal_type)
2195 return 0x7;
2196 if (pdt->p_conf_header->b_init_active_icc_level != dev.b_init_active_icc_level)
2197 return 0x8;
2198 if (pdt->p_conf_header->w_periodic_rtc_update != dev.w_periodic_rtc_update)
2199 return 0x9;
2200
2201 return compair_unit_part(pdt);
2202 }
2203
2204 /***************************************************************
2205 * ufs_device_init
2206 * Description: The function does the following
2207 * 1. Sends the NOP Out command continuosly till it passes
2208 * 2. Sets the Device init Flag for UFS Device initialization
2209 *
2210 ****************************************************************/
ufs_device_init(void)2211 static int ufs_device_init(void)
2212 {
2213 int ret;
2214 uint8_t flags_ret_val = 1;
2215 int retry = 3000; /* retry 3000 times */
2216
2217 /* Send continuos NOP OUT Command unless Response is Valid */
2218 ret = send_nop_out_cmd();
2219 if (ret != UFS_SUCCESS) {
2220 printf("nop out fail\n");
2221 return ret;
2222 }
2223
2224 /* Set the Device Init Flag */
2225 ret = ufs_set_flag(FDEVICE_INIT, &flags_ret_val);
2226 if (ret) {
2227 printf("set device init flag fail\n");
2228 return ret;
2229 }
2230
2231 do {
2232 ret = ufs_read_flag(FDEVICE_INIT, &flags_ret_val);
2233 if ((ret == UFS_SUCCESS) && (flags_ret_val == 0)) {
2234 return UFS_SUCCESS;
2235 }
2236 ufs_waitms(1);
2237 } while (--retry > 0);
2238
2239 if (flags_ret_val != 0)
2240 ret = UFS_FDEVICE_INIT_FAIL;
2241
2242 printf("read device init fail\n");
2243
2244 return ret;
2245 }
2246
ufs_host_init(void)2247 static int ufs_host_init(void)
2248 {
2249 int ret;
2250
2251 ret = ufs_soft_init();
2252 if (ret) {
2253 printf("ufs_soft_init fail\n");
2254 return ret;
2255 }
2256
2257 ret = ufs_hc_enable();
2258 if (ret) {
2259 printf("HC enable fail\n");
2260 return ret;
2261 }
2262 ufs_hc_init();
2263
2264 ret = ufs_link_startup();
2265 if (ret) {
2266 printf("link start up fail\n");
2267 return ret;
2268 }
2269
2270 ufs_config_init();
2271 printf("\nUFS Linkup!\n");
2272
2273 return UFS_SUCCESS;
2274 }
2275
2276 /*
2277 * some device need a full reset after lu config
2278 * And this funciton does not switch to hs mode
2279 * after lu config and ufs_reset init would continue and switch to hs mode
2280 */
ufs_reset(void)2281 static int ufs_reset(void)
2282 {
2283 int ret;
2284
2285 get_local_dwc_host();
2286
2287 ufs_hardware_init();
2288
2289 ret = ufs_host_init();
2290 if (ret) {
2291 printf("UfsHostInit ret:%d\n", ret);
2292 return ret;
2293 }
2294
2295 /* device reset will cause a new UAC */
2296 memset(dwc_host->lu_request_sense_sent, 0, UNIT_DESCS_COUNT);
2297
2298 ret = ufs_device_init();
2299 if (ret)
2300 printf("UfsDeviceInit ret:%d\n", ret);
2301
2302 return ret;
2303 }
2304
update_geometry_info(struct partition_desc_table * pdt)2305 static void update_geometry_info(struct partition_desc_table *pdt)
2306 {
2307 struct ufs_geometry_descriptor geo;
2308
2309 geo = g_ufs_desc.geo_desc;
2310
2311 pdt->q_total_raw_device_capacity = cpu_to_be64(geo.q_total_raw_device_capacity);
2312 pdt->d_segment_size = to_bigendian32(geo.d_segment_size);
2313 pdt->b_allocation_unit_size = geo.b_allocation_unit_size;
2314 pdt->b_data_ordering = geo.b_data_ordering;
2315 pdt->b_max_contex_id_number = geo.b_max_contex_id_number;
2316 pdt->w_supported_memory_types = to_bigendian16(geo.w_supported_memory_types);
2317 pdt->d_system_code_max_alloc_u = to_bigendian32(geo.d_system_code_max_alloc_u);
2318 pdt->w_system_code_cap_adj_fac = to_bigendian16(geo.w_system_code_cap_adj_fac);
2319 pdt->d_non_persist_max_alloc_u = to_bigendian32(geo.d_non_persist_max_alloc_u);
2320 pdt->w_non_persist_cap_adj_fac = to_bigendian16(geo.w_non_persist_cap_adj_fac);
2321 pdt->d_enhanced1_max_alloc_u = to_bigendian32(geo.d_enhanced1_max_alloc_u);
2322 pdt->w_enhanced1_cap_adj_fac = to_bigendian16(geo.w_enhanced1_cap_adj_fac);
2323 pdt->d_enhanced2_max_alloc_u = to_bigendian32(geo.d_enhanced2_max_alloc_u);
2324 pdt->w_enhanced2_cap_adj_fac = to_bigendian16(geo.w_enhanced2_cap_adj_fac);
2325 }
2326
ufs_get_device_info(void)2327 static int ufs_get_device_info(void)
2328 {
2329 int ret;
2330
2331 get_local_dwc_host();
2332
2333 memset((void *)&g_ufs_desc, 0, (unsigned int)sizeof(struct ufs_descriptor));
2334
2335 ret = ufs_read_descriptor((void *)(&g_ufs_desc.dev_desc),
2336 DEVICE_DESC, 0, DEVICE_DESC_LENGTH);
2337 if (ret != UFS_OK) {
2338 printf("read device descriptor fail\n");
2339 return UFS_ERR;
2340 }
2341
2342 ret = ufs_read_descriptor((void *)(&g_ufs_desc.geo_desc),
2343 GEOMETRY_DESC, 0, GEOMETRY_DESC_LENGTH);
2344 if (ret != UFS_OK) {
2345 printf("read geometry descriptor fail\n");
2346 return ret;
2347 }
2348
2349 ret = ufs_read_string_descriptor();
2350 if (ret != UFS_OK) {
2351 printf("read string descriptor fail\n");
2352 return UFS_ERR;
2353 }
2354
2355 /* configuration unit descriptor offset/length */
2356 dwc_host->unit_offset = g_ufs_desc.dev_desc.b_ud_0base_offset;
2357 dwc_host->unit_length = g_ufs_desc.dev_desc.b_ud_config_plength;
2358
2359 /* device specification version */
2360 dwc_host->dev_spec_version =
2361 to_bigendian16(g_ufs_desc.dev_desc.w_spec_version);
2362 dwc_host->manufacturer_id =
2363 to_bigendian16(g_ufs_desc.dev_desc.w_manufacturer_id);
2364 dwc_host->manufacturer_date =
2365 to_bigendian16(g_ufs_desc.dev_desc.w_manufacture_date);
2366
2367 printf(" MID: 0x%x\n", dwc_host->manufacturer_id);
2368 printf(" Version: 0x%x\n", dwc_host->dev_spec_version);
2369 printf(" Device: %s\n", g_ufs_desc.str_desc.product_name);
2370 printf(" Size: 0x%llx\n", cpu_to_be64(g_ufs_desc.geo_desc.q_total_raw_device_capacity));
2371 printf(" Block: %d Bytes\n", LOGICAL_BLK_SIZE);
2372
2373 return UFS_OK;
2374 }
2375
ufs_device_configuration(struct partition_desc_table * pdt,struct desc_params * params,struct dwc_ufs_query_upiu * resp_upiu)2376 static int ufs_device_configuration(struct partition_desc_table *pdt,
2377 struct desc_params *params,
2378 struct dwc_ufs_query_upiu *resp_upiu)
2379 {
2380 int ret;
2381 uint32_t value;
2382
2383 ret = read_attribute(B_CONFIG_DESC_LOCK, 0, 0, &value);
2384 if (ret != UFS_SUCCESS) {
2385 printf("read bConfigDescrLock fail. ret = %d\n", ret);
2386 } else {
2387 printf("bConfigDescrLock = 0x%x\n", value);
2388 if (value == 1) {
2389 printf("write config desc fail: descriptor locked\n");
2390 return -1;
2391 }
2392 }
2393
2394 /* response of configuration descriptor sent as request UPIU */
2395 params->req_upiu = resp_upiu;
2396 params->conf_head = pdt->p_conf_header;
2397 params->part_desc = pdt->partition_desc_ptr;
2398 params->opcode = WRITE_DESC_OPCODE;
2399 params->desc_idn = CONFIGURATION_DESC;
2400 params->desc_index = 0;
2401 params->length = CONFIGURATION_DESC_LENGTH;
2402 modify_desc_upiu(params);
2403
2404 ret = write_descriptor(params->req_upiu);
2405 if (ret != UFS_SUCCESS) {
2406 printf("write configuration fail. ret = %d\n", ret);
2407 return ret;
2408 }
2409
2410 ret = ufs_reset();
2411 if (ret) {
2412 printf("ufs_reset fail. ret = %d\n", ret);
2413 return ret;
2414 }
2415
2416 return 0;
2417 }
2418
2419 /***************************************************************
2420 * ufs_create_partition_inventory
2421 * Description: The Function does the following actions
2422 *
2423 * 1. Reads UNIT desc's and stores the qphymemrescnt of each lun
2424 * 2. Reads the Device Descriptor to know the Configureable Unit
2425 * desc zero's Offset and length of all unit descriptors.
2426 * 3. Validates the qmemrescnt with the configuration desc contents
2427 * 4. Reads and edits the content of configuration desc as per the
2428 * input arguments
2429 *
2430 ***************************************************************/
ufs_create_partition_inventory(uint8_t partition_mask,struct partition_desc_table * pdt)2431 static int ufs_create_partition_inventory(uint8_t partition_mask, struct partition_desc_table *pdt)
2432 {
2433 int ret;
2434 struct desc_params params;
2435 struct dwc_ufs_query_upiu *req_upiu = NULL;
2436 void *resp_upiu = NULL;
2437 uint8_t i;
2438
2439 get_local_dwc_host();
2440 /* use slot 0 default */
2441 resp_upiu = dwc_host->lrb[0].resp_upiu;
2442 req_upiu = (struct dwc_ufs_query_upiu *)(dwc_host->lrb[0].cmd_upiu);
2443
2444 /* update the geometry information */
2445 update_geometry_info(pdt);
2446
2447 /* Validate the Input Arguments */
2448 for (i = 0; i < UNIT_DESCS_COUNT; i++) {
2449 if ((partition_mask & (BIT(i))) == 0)
2450 pdt->partition_desc_ptr[i] = NULL;
2451 }
2452
2453 update_lu_capacity_info(pdt);
2454
2455 /* read configuration descriptor */
2456 params.req_upiu = req_upiu;
2457 params.part_desc = NULL;
2458 params.opcode = READ_DESC_OPCODE;
2459 params.desc_idn = CONFIGURATION_DESC;
2460 params.desc_index = 0;
2461 params.length = CONFIGURATION_DESC_LENGTH;
2462 modify_desc_upiu(¶ms);
2463
2464 ret = read_descriptor(req_upiu, &resp_upiu);
2465 if (ret != UFS_SUCCESS) {
2466 printf("read configuration fail. ret = %d\n", ret);
2467 return ret;
2468 }
2469 memcpy(&g_ufs_desc.conf_desc, (void *)((u8 *)resp_upiu + QUERY_RESPONSE_HEAD_OFFSET), CONFIGURATION_DESC_LENGTH);
2470
2471 ret = compair_conf_desp(pdt);
2472 if (!ret)
2473 return 0;
2474
2475 printf("compair conf desp fail. ret=%d\n", ret);
2476 printf("UFS enter device configuration\n");
2477
2478 ret = ufs_device_configuration(pdt, ¶ms, resp_upiu);
2479 if (ret) {
2480 printf("ufs device configuration fail. ret = %d\n", ret);
2481 return ret;
2482 }
2483
2484 return 0;
2485 }
2486
ufs_set_bootlun(uint8_t lun)2487 int ufs_set_bootlun(uint8_t lun)
2488 {
2489 uint32_t value;
2490 int ret;
2491
2492 ret = read_attribute(B_BOOT_LUNEN, 0, 0, &value);
2493 if (ret != UFS_SUCCESS) {
2494 printf("read bBootLunEn fail. ret = %d\n", ret);
2495 return ret;
2496 }
2497
2498 if ((lun + 1) == value) {
2499 printf("Same UFS Lu%d Boot W-Lun\n", (value - 1));
2500 return 0;
2501 }
2502
2503 /* set default boot from Boot LU A */
2504 value = lun + 1;
2505 ret = write_attribute(B_BOOT_LUNEN, 0, 0, &value);
2506 if (ret) {
2507 printf("write bBootLunEn attribute fail. ret = %d\n", ret);
2508 return ret;
2509 }
2510 printf("new UFS Lu%d Boot W-Lun\n", (value - 1));
2511 return ret;
2512 }
2513
set_boot_lu_enable(void)2514 static int set_boot_lu_enable(void)
2515 {
2516 uint32_t value = 0;
2517 uint32_t target_value = DEFAULT_BOOT_LUN;
2518 int ret;
2519
2520 ret = read_attribute(B_BOOT_LUNEN, 0, 0, &value);
2521 if (ret != UFS_SUCCESS) {
2522 printf("read bBootLunEn fail. ret = %d\n", ret);
2523 return ret;
2524 }
2525
2526 if (value != 0)
2527 printf("UFS get boot W-LU-%c\n",
2528 (value == WELL_BOOT_LU_A) ? 'A' : 'B');
2529
2530 if (value == target_value)
2531 return 0;
2532
2533 /* set default boot from Boot LU A */
2534 value = target_value;
2535 ret = write_attribute(B_BOOT_LUNEN, 0, 0, &value);
2536 if (ret) {
2537 printf("write bBootLunEn attribute fail. ret = %d\n", ret);
2538 return ret;
2539 }
2540
2541 printf("UFS set boot W-LU(%c)\n", (value == WELL_BOOT_LU_A) ? 'A' : 'B');
2542 return ret;
2543 }
2544
ufs_lu_configuration(struct partition_desc_table * pdt)2545 static void ufs_lu_configuration(struct partition_desc_table *pdt)
2546 {
2547 int i;
2548
2549 get_local_dwc_host();
2550
2551 /* configuration header */
2552 pdt->p_conf_header->b_boot_enable = 0x1;
2553 pdt->p_conf_header->b_descr_access_en = 0x0;
2554 pdt->p_conf_header->b_init_power_mode = 0x1;
2555 pdt->p_conf_header->b_high_priority_lun = 0x7F;
2556 pdt->p_conf_header->b_secure_removal_type = 0x0;
2557 pdt->p_conf_header->b_init_active_icc_level = 0x0;
2558 pdt->p_conf_header->w_periodic_rtc_update = 0x0;
2559
2560 /* lu 0: boot lu A */
2561 pdt->partition_desc_ptr[0]->boot_lun_id = WELL_BOOT_LU_A; /* lu 0, boot a */
2562 if (dwc_host->manufacturer_id == UFS_MANUFACTURER_ID_TOSHIBA)
2563 pdt->partition_desc_ptr[0]->memory_type = 0x4; /* lu 0, Enhanced Memory */
2564 else
2565 pdt->partition_desc_ptr[0]->memory_type = 0x3; /* lu 0, Enhanced Memory */
2566 pdt->partition_desc_ptr[0]->lu_capacity = 4; /* lu 0, 4MB */
2567
2568 /* lu 1: boot lu B */
2569 pdt->partition_desc_ptr[1]->boot_lun_id = WELL_BOOT_LU_B; /* lu 1, boot b */
2570 if (dwc_host->manufacturer_id == UFS_MANUFACTURER_ID_TOSHIBA)
2571 pdt->partition_desc_ptr[0]->memory_type = 0x4; /* lu 0, Enhanced Memory */
2572 else
2573 pdt->partition_desc_ptr[0]->memory_type = 0x3; /* lu 0, Enhanced Memory */
2574 pdt->partition_desc_ptr[1]->lu_capacity = 4; /* lu 1, 4MB */
2575
2576 /* lu 2: data lu */
2577 pdt->partition_desc_ptr[2]->boot_lun_id = 0x0; /* lu 2 */
2578 pdt->partition_desc_ptr[2]->memory_type = 0x3; /* lu 2, Enhanced Memory */
2579 pdt->partition_desc_ptr[2]->lu_capacity = 8; /* lu 2, 8MB */
2580
2581 /* lu 3: data lu */
2582 pdt->partition_desc_ptr[3]->boot_lun_id = 0x0; /* lu 3 */
2583 pdt->partition_desc_ptr[3]->memory_type = 0x0; /* lu 3, Normal Memory */
2584 pdt->partition_desc_ptr[3]->lu_capacity = UFS_MAX_LU_CAP; /* lu 3, max capacity */
2585
2586 for (i = 0; i <= 3; i++) { /* lu 0 - 3 */
2587 pdt->partition_desc_ptr[i]->write_protect = 0x0;
2588 pdt->partition_desc_ptr[i]->data_reliability = 0x1;
2589 pdt->partition_desc_ptr[i]->block_size = 0x0c;
2590 pdt->partition_desc_ptr[i]->prov_type = 0x2;
2591 pdt->partition_desc_ptr[i]->context_capabilities = 0x0;
2592 }
2593 }
2594
ufs_lu_init(void)2595 static int ufs_lu_init(void)
2596 {
2597 struct partition_desc_table pdt = {0};
2598 struct partition_desc partition_desc_ptr[UNIT_DESCS_COUNT] = {{0}};
2599 struct configuration_header config_header = {0};
2600 unsigned int bootlun = 0;
2601 int i, ret;
2602
2603 get_local_dwc_host();
2604
2605 pdt.p_conf_header = &config_header;
2606 for (i = 0; i < UNIT_DESCS_COUNT; i++)
2607 pdt.partition_desc_ptr[i] = &partition_desc_ptr[i];
2608
2609 ufs_lu_configuration(&pdt);
2610
2611 ret = ufs_create_partition_inventory(0xf, &pdt);
2612 if (ret) {
2613 goto out;
2614 }
2615
2616 ret = set_boot_lu_enable();
2617 if (ret) {
2618 goto out;
2619 }
2620
2621 ret = read_attribute(B_BOOT_LUNEN, 0, 0, &bootlun);
2622 if (ret != UFS_SUCCESS) {
2623 printf("read bBootLunEn fail. ret = %d\n", ret);
2624 return ret;
2625 }
2626
2627 for (i = 0; i < UNIT_DESCS_COUNT; i++) {
2628 if (pdt.partition_desc_ptr[i] &&
2629 pdt.partition_desc_ptr[i]->boot_lun_id == bootlun) {
2630 printf("UFS config LU-%d to W-LU-%c\n", i,
2631 (bootlun == WELL_BOOT_LU_A) ? 'A' : 'B');
2632 dwc_host->active_bootlun = i;
2633 break;
2634 }
2635 }
2636 out:
2637 return ret;
2638 }
2639
ufs_set_ref_clk(void)2640 static int ufs_set_ref_clk(void)
2641 {
2642 uint32_t value;
2643 int ret;
2644 uint32_t target_ref_clk;
2645
2646 target_ref_clk = 0; /* 19.2MHz */
2647
2648 ret = read_attribute(B_REFCLK_FREQ, 0, 0, &value);
2649 if (ret != UFS_SUCCESS) {
2650 printf("read bRefClkFreq fail. ret = %d\n", ret);
2651 return ret;
2652 }
2653
2654 if (target_ref_clk == value)
2655 return 0;
2656
2657 /* set default boot from Boot LU A */
2658 ret = write_attribute(B_REFCLK_FREQ, 0, 0, &target_ref_clk);
2659 if (ret) {
2660 printf("write bRefClkFreq attribute fail. ret = %d\n", ret);
2661 return ret;
2662 }
2663
2664 ret = read_attribute(B_REFCLK_FREQ, 0, 0, &value);
2665 if (ret != UFS_SUCCESS) {
2666 printf("read bRefClkFreq fail. ret = %d\n", ret);
2667 return ret;
2668 }
2669
2670 if (target_ref_clk == value)
2671 return UFS_OK;
2672
2673 return UFS_ERR;
2674 }
2675
ufs_read_capacity(uint32_t * lba)2676 int ufs_read_capacity(uint32_t *lba)
2677 {
2678 uint32_t *data = NULL;
2679 int ret;
2680
2681 get_local_dwc_host();
2682
2683 data = (uint32_t *)dwc_host->wr_buf;
2684
2685 ret = do_scsi_cmd(UFS_OP_READ_CAPACITY_10, DMA_FROM_DEVICE,
2686 (uint64_t)(uintptr_t)data, 0, CAPACITY_DATA_LENGTH);
2687 if (ret != UFS_SUCCESS) {
2688 printf("send READ_CAPACITY_10 error: %d\n", ret);
2689 return ret;
2690 }
2691
2692 *lba = to_bigendian32(*data) + 1;
2693 return ret;
2694 }
2695
ufs_request_sense(void)2696 static int ufs_request_sense(void)
2697 {
2698 uint8_t *sense_data = NULL;
2699 int ret;
2700
2701 get_local_dwc_host();
2702
2703 sense_data = (uint8_t *)dwc_host->wr_buf;
2704
2705 ret = do_scsi_cmd(UFS_OP_REQUEST_SENSE, DMA_FROM_DEVICE,
2706 (uint64_t)(uintptr_t)sense_data, 0, SENSE_DATA_LENGTH);
2707
2708 return ret;
2709 }
2710
2711 /****************************************************************
2712 * ufs_set_active_lun
2713 * Description: Sets the Lun Number for further Transactions
2714 *
2715 ***************************************************************/
ufs_set_active_lun(uint8_t lun)2716 int ufs_set_active_lun(uint8_t lun)
2717 {
2718 int ret;
2719
2720 get_local_dwc_host();
2721
2722 dwc_host->active_lun = lun;
2723 if (lun >= UNIT_DESCS_COUNT) {
2724 printf("well known lun: 0x%x\n", lun);
2725
2726 if (g_wlun == lun)
2727 return UFS_SUCCESS;
2728
2729 /* issue REQUEST SENSE command once for lu before accessing it */
2730 ret = ufs_request_sense();
2731 if (ret != 0) {
2732 printf("send UFS_OP_REQUEST_SENSE error: %d\n", ret);
2733 return ret;
2734 }
2735 printf("send UFS_OP_REQUEST_SENSE success: %d\n", ret);
2736 g_wlun = lun;
2737 return UFS_SUCCESS;
2738 }
2739
2740 printf("UFS set active LU-%d\n", lun);
2741 if (dwc_host->lu_request_sense_sent[lun])
2742 return UFS_SUCCESS;
2743
2744 /* issue REQUEST SENSE command once for lu before accessing it */
2745 ret = ufs_request_sense();
2746 if (ret != 0) {
2747 printf("send UFS_OP_REQUEST_SENSE error: %d\n", ret);
2748 return ret;
2749 }
2750
2751 dwc_host->lu_request_sense_sent[lun] = 1;
2752 return ret;
2753 }
2754
2755 /***************************************************************
2756 * ufs_sync_storage
2757 * Description: Synchronizes the content of the cache to the media.
2758 *
2759 ****************************************************************/
ufs_sync_storage(void)2760 static int ufs_sync_storage(void)
2761 {
2762 int ret;
2763
2764 /* Send Synchronize Cache 10 Command and handle its completion */
2765 ret = do_scsi_cmd(UFS_OP_SYNCHRONIZE_CACHE_10, 0, 0, 0, 0);
2766 if (ret != UFS_SUCCESS) {
2767 printf("send SYNCHRONIZE_CACHE_10 error: %d\n", ret);
2768 return ret;
2769 }
2770
2771 return ret;
2772 }
2773
2774 /***************************************************************
2775 * ufs_write_storage
2776 * Description: Writes the content of the source Address to
2777 * destination offset of the active lun.
2778 * The APi assumes the data buffes if unaligned have
2779 * valid data above the start address
2780 *
2781 ****************************************************************/
ufs_write_storage(uint64_t src_addr,uint64_t dest_offset,uint32_t size)2782 int ufs_write_storage(uint64_t src_addr, uint64_t dest_offset, uint32_t size)
2783 {
2784 int ret;
2785 uint32_t len;
2786 uint64_t src_addr_tmp = src_addr;
2787 uint32_t size_tmp = size;
2788 uint32_t maxsize = PRDT_BUFFER_SIZE * DWC_UFSHCD_MAX_PRD_SIZE;
2789
2790 while (size_tmp) {
2791 if (size_tmp < maxsize)
2792 len = size_tmp;
2793 else
2794 len = maxsize;
2795
2796 /* Send Write 10 Command and handle its completion */
2797 ret = do_scsi_cmd(UFS_OP_WRITE_10, DMA_TO_DEVICE,
2798 src_addr_tmp, dest_offset, len);
2799 if (ret != UFS_SUCCESS) {
2800 printf("send WRITE_10 error: %d\n", ret);
2801 return ret;
2802 }
2803 size_tmp -= len;
2804 src_addr_tmp += len;
2805 dest_offset += len;
2806 }
2807
2808 ret = ufs_sync_storage();
2809 return ret;
2810 }
2811
2812 /********************************************************************
2813 * ufs_read_storage
2814 * Description: Reads the content of the source offset of active lun
2815 * and copies the content to dest_addr.
2816 * The API assumes there is enough memory allocated and
2817 * available above and below start address for unaligned
2818 * and multi block access
2819 *
2820 ********************************************************************/
ufs_read_storage(uint64_t dest_addr,uint64_t src_offset,uint32_t size)2821 int ufs_read_storage(uint64_t dest_addr, uint64_t src_offset, uint32_t size)
2822 {
2823 int ret = -1;
2824 uint32_t len;
2825 uint64_t dest_addr_tmp = dest_addr;
2826 uint32_t size_tmp = size;
2827 uint32_t maxsize = (PRDT_BUFFER_SIZE * DWC_UFSHCD_MAX_PRD_SIZE);
2828
2829 while (size_tmp) {
2830 if (size_tmp < maxsize)
2831 len = size_tmp;
2832 else
2833 len = maxsize;
2834
2835 /* Send Read 10 Command and handle its completion */
2836 ret = do_scsi_cmd(UFS_OP_READ_10, DMA_FROM_DEVICE,
2837 dest_addr_tmp, src_offset, len);
2838 if (ret != UFS_SUCCESS) {
2839 printf("send READ_10 error: %d\n", ret);
2840 return ret;
2841 }
2842 size_tmp -= len;
2843 dest_addr_tmp += len;
2844 src_offset += len;
2845 }
2846
2847 return ret;
2848 }
2849
ufs_write_boot_storage(uint64_t dest_addr,uint64_t src_offset,uint32_t size)2850 int ufs_write_boot_storage(uint64_t dest_addr, uint64_t src_offset, uint32_t size)
2851 {
2852 int ret;
2853 int prelun;
2854
2855 get_local_dwc_host();
2856
2857 prelun = dwc_host->active_lun;
2858 ret = ufs_set_active_lun(dwc_host->active_bootlun);
2859 if (ret != 0) {
2860 return ret;
2861 }
2862
2863 ret = ufs_write_storage(dest_addr, src_offset, size);
2864 if (ret != 0) {
2865 return ret;
2866 }
2867
2868 ret = ufs_set_active_lun(prelun);
2869
2870 return ret;
2871 }
2872
ufs_read_boot_storage(uint64_t dest_addr,uint64_t src_offset,uint32_t size)2873 int ufs_read_boot_storage(uint64_t dest_addr, uint64_t src_offset, uint32_t size)
2874 {
2875 int ret;
2876 int prelun;
2877
2878 get_local_dwc_host();
2879
2880 prelun = dwc_host->active_lun;
2881 ret = ufs_set_active_lun(dwc_host->active_bootlun);
2882 if (ret != 0) {
2883 return ret;
2884 }
2885
2886 ret = ufs_read_storage(dest_addr, src_offset, size);
2887 if (ret != 0) {
2888 return ret;
2889 }
2890
2891 ret = ufs_set_active_lun(prelun);
2892
2893 return ret;
2894 }
2895
ufs_hibernate_enter(void)2896 int ufs_hibernate_enter(void)
2897 {
2898 unsigned int value;
2899 uint32_t retry = 500; /* wait 500ms to let device finish the device hibernate exit */
2900
2901 /* 1. BUSTHRTL bit12 clear to 0 */
2902 value = dwc_ufs_read_reg(UFS_BUSTHRTL_OFF);
2903 if (value & CGE) {
2904 value &= (~CGE);
2905 dwc_ufs_write_reg(UFS_BUSTHRTL_OFF, value);
2906 }
2907
2908 /* 2. enter hibernate */
2909 send_uic_command(DME_HIBERNATE_ENTER, 0, 0, 0);
2910
2911 /* 3. detect enter success or not */
2912 while (retry--) {
2913 if (dwc_ufs_read_reg(UFS_IS_OFF) & UFS_IS_UHES_BIT)
2914 break;
2915 ufs_waitms(1);
2916 }
2917 /* 3.1 if fail */
2918 if (retry == 0xFFFFFFFF) {
2919 printf("ufs_hibernate_enter fail, UHES wait 500ms timeout\n");
2920 return UFS_ERR;
2921 }
2922 /* 3.2 if success */
2923 printf("ufs_hibernate_enter success.\n");
2924 return UFS_OK;
2925 }
2926
ufs_hibernate_exit(void)2927 int ufs_hibernate_exit(void)
2928 {
2929 unsigned int value;
2930 uint32_t retry = 500; /* wait 500ms to let device finish the device hibernate exit */
2931
2932 /* 1. BUSTHRTL bit12 clear to 0 */
2933 value = dwc_ufs_read_reg(UFS_BUSTHRTL_OFF);
2934 if (value & CGE) {
2935 value &= (~CGE);
2936 dwc_ufs_write_reg(UFS_BUSTHRTL_OFF, value);
2937 }
2938
2939 /* 2. exit hibernate */
2940 send_uic_command(DME_HIBERNATE_EXIT, 0, 0, 0);
2941
2942 /* 3. detect exit success or not */
2943 while (retry--) {
2944 if (dwc_ufs_read_reg(UFS_IS_OFF) & UFS_IS_UHXS_BIT)
2945 break;
2946 ufs_waitms(1);
2947 }
2948 /* 3.1 if fail, dump reg */
2949 if (retry == 0xFFFFFFFF) {
2950 printf("ufs_hibernate_exit fail, UHXS wait 500ms timeout\n");
2951 return UFS_ERR;
2952 }
2953 /* 3.2 if success */
2954 printf("ufs_hibernate_exit success.\n");
2955 return UFS_OK;
2956 }
2957
2958 /***************************************************************
2959 * do_flag_operation
2960 * Description: The function can be used for any operation on flags
2961 * 1. fills the query upiu memory content
2962 * 2. Handles the response of query command sent
2963 * 3. updates the flag return value
2964 *
2965 ***************************************************************/
do_flag_operation(int opcode,int query_func,enum flags_id idn,uint8_t * flags_ret)2966 static int do_flag_operation(int opcode, int query_func, enum flags_id idn, uint8_t *flags_ret)
2967 {
2968 int ret;
2969 uint8_t val[4] = {0}; /* 4 byte value */
2970 uint8_t free_slot;
2971 struct query_param param = {(uint8_t)opcode, (uint8_t)idn, 0, 0};
2972
2973 get_local_dwc_host();
2974
2975 free_slot = dwc_ufshcd_get_xfer_req_free_slot(dwc_host);
2976 if (free_slot == BAD_SLOT)
2977 return UFS_ERR;
2978
2979 create_query_upiu((uint8_t)query_func, ¶m, val, free_slot);
2980
2981 ret = wait_for_cmd_completion(BIT(free_slot));
2982 if (ret != UFS_SUCCESS) {
2983 return ret;
2984 }
2985
2986 ret = handle_query_response(val, free_slot);
2987 *flags_ret = val[0];
2988
2989 return ret;
2990 }
2991
2992 /***************************************************************
2993 * ufs_set_flag
2994 * Description: The function invokes do_flag_operation for set
2995 * flag operation
2996 *
2997 ***************************************************************/
ufs_set_flag(enum flags_id idn,uint8_t * flags_ret)2998 int ufs_set_flag(enum flags_id idn, uint8_t *flags_ret)
2999 {
3000 int ret;
3001
3002 ret = do_flag_operation(SET_FLAG_OPCODE, STANDARD_WR_REQ, idn, flags_ret);
3003
3004 return ret;
3005 }
3006
modify_write_conf_desc(const struct desc_params * params)3007 static void modify_write_conf_desc(const struct desc_params *params)
3008 {
3009 uint8_t *data = NULL;
3010 struct partition_desc **desc = params->part_desc;
3011 struct dwc_ufs_query_upiu *upiu_ptr = (struct dwc_ufs_query_upiu *)params->req_upiu;
3012 uint32_t i, offset;
3013
3014 get_local_dwc_host();
3015
3016 data = (uint8_t *)(upiu_ptr + 1);
3017 /* boot enable */
3018 data[0x3] = params->conf_head->b_boot_enable;
3019 data[0x4] = params->conf_head->b_descr_access_en;
3020 data[0x5] = params->conf_head->b_init_power_mode;
3021 data[0x6] = params->conf_head->b_high_priority_lun;
3022 data[0x7] = params->conf_head->b_secure_removal_type;
3023 data[0x8] = params->conf_head->b_init_active_icc_level;
3024 data[0x9] = (uint8_t)(((params->conf_head->w_periodic_rtc_update) >> 8) & 0xff); /* shift 8 */
3025 data[0xA] = (uint8_t)((params->conf_head->w_periodic_rtc_update) & 0xff);
3026 for (i = 0; i < UNIT_DESCS_COUNT; i++) {
3027 offset = dwc_host->unit_length * i + dwc_host->unit_offset;
3028 if (desc[i] == NULL) {
3029 /* Disable the Lun */
3030 data[offset] = 0x0;
3031 continue;
3032 }
3033 data[offset] = 0x1;
3034 data[offset + 0x1] = desc[i]->boot_lun_id;
3035 data[offset + 0x2] = desc[i]->write_protect;
3036 data[offset + 0x3] = desc[i]->memory_type;
3037 data[offset + 0x4] = (uint8_t)(((desc[i]->num_alloc_units) >> 24) & 0xff); /* shift 24 */
3038 data[offset + 0x5] = (uint8_t)(((desc[i]->num_alloc_units) >> 16) & 0xff); /* shift 16 */
3039 data[offset + 0x6] = (uint8_t)(((desc[i]->num_alloc_units) >> 8) & 0xff); /* shift 8 */
3040 data[offset + 0x7] = (uint8_t)((desc[i]->num_alloc_units) & 0xff);
3041 data[offset + 0x8] = desc[i]->data_reliability;
3042 data[offset + 0x9] = desc[i]->block_size;
3043 data[offset + 0xa] = desc[i]->prov_type;
3044 data[offset + 0xb] = (uint8_t)(((desc[i]->context_capabilities) >> 8) & 0xff); /* shift 8 */
3045 data[offset + 0xc] = (uint8_t)((desc[i]->context_capabilities) & 0xff);
3046 }
3047 }
3048
3049 /***************************************************************
3050 * modify_desc_upiu
3051 * Description: The function performs the following
3052 * 1.Fills the request upiu for read/write desc operation
3053 * 2.Updates the Data Memory below the request UPIU
3054 *
3055 ***************************************************************/
modify_desc_upiu(const struct desc_params * params)3056 void modify_desc_upiu(const struct desc_params *params)
3057 {
3058 uint32_t i;
3059 struct dwc_ufs_query_upiu *upiu_ptr = NULL;
3060
3061 /* Command Descriptor Programming */
3062 upiu_ptr = (struct dwc_ufs_query_upiu *)params->req_upiu;
3063 upiu_ptr->trans_type = 0x16;
3064 upiu_ptr->flags = UPIU_CMD_FLAGS_NONE;
3065 upiu_ptr->reserved_1 = 0x00;
3066 upiu_ptr->task_tag = 0x01;
3067 upiu_ptr->reserved_2 = 0x00;
3068
3069 if (params->opcode == READ_DESC_OPCODE)
3070 upiu_ptr->query_func = STANDARD_RD_REQ;
3071 else
3072 upiu_ptr->query_func = STANDARD_WR_REQ;
3073
3074 upiu_ptr->query_resp = 0x00;
3075 upiu_ptr->reserved_3 = 0x00;
3076 upiu_ptr->tot_ehs_len = 0x00;
3077 if (params->opcode == READ_DESC_OPCODE)
3078 upiu_ptr->data_seg_len = 0x00;
3079 else
3080 upiu_ptr->data_seg_len = (to_bigendian16(params->length));
3081
3082 for (i = 0; i < 16; i++) /* clear 16 tsf */
3083 upiu_ptr->tsf[i] = 0x0;
3084 upiu_ptr->tsf[0] = params->opcode; /* 0: opcode */
3085 upiu_ptr->tsf[1] = params->desc_idn; /* 1: idn */
3086 upiu_ptr->tsf[2] = params->desc_index; /* 2: index */
3087 upiu_ptr->tsf[6] = (uint8_t)(params->length >> 8); /* 6: MSB shift 8 */
3088 upiu_ptr->tsf[7] = params->length & 0xff; /* 7: LSB */
3089 upiu_ptr->reserved_5 = 0x0;
3090
3091 if ((params->opcode == WRITE_DESC_OPCODE) && (params->desc_idn == CONFIGURATION_DESC))
3092 modify_write_conf_desc(params);
3093 }
3094
3095 /***************************************************************
3096 * read_descriptor
3097 * Description: The functon populates the request upiu structure
3098 * with upiu info passed in 1st argument
3099 *
3100 ***************************************************************/
read_descriptor(const void * req_upiu,void ** resp_upiu_out)3101 int read_descriptor(const void *req_upiu, void **resp_upiu_out)
3102 {
3103 int ret;
3104 struct dwc_ufs_utrd *utrd = NULL;
3105 struct dwc_ufs_resp_upiu *resp_upiu = NULL;
3106 uint8_t free_slot;
3107
3108 get_local_dwc_host();
3109
3110 free_slot = dwc_ufshcd_get_xfer_req_free_slot(dwc_host);
3111 if (free_slot == BAD_SLOT)
3112 return UFS_ERR;
3113
3114 utrd = dwc_host->lrb[free_slot].utrd;
3115 resp_upiu = dwc_host->lrb[free_slot].resp_upiu;
3116
3117 /* UTRD Descriptor Programming for processing command */
3118 utrd->ct_and_flags = (uint8_t)
3119 (UTP_NO_DATA_TRANSFER | UTP_UFS_STORAGE_COMMAND);
3120 utrd->resp_upiu_length = to_littleendian16((uint16_t)
3121 (DWC_UCD_ALIGN >> UFS_DWORD_SHIFT));
3122 utrd->prdt_length = 0;
3123
3124 create_desc_upiu(req_upiu, free_slot);
3125
3126 ret = wait_for_cmd_completion(BIT(free_slot));
3127 if (ret != UFS_SUCCESS) {
3128 return ret;
3129 }
3130
3131 *(resp_upiu_out) = resp_upiu;
3132
3133 ret = handle_query_response(NULL, free_slot);
3134 return ret;
3135 }
3136
3137 /***************************************************************
3138 * ufs_read_flag
3139 * Description: The function invokes do_flag_operation for Read
3140 * flag operation
3141 *
3142 ***************************************************************/
ufs_read_flag(enum flags_id idn,uint8_t * flags_ret)3143 int ufs_read_flag(enum flags_id idn, uint8_t *flags_ret)
3144 {
3145 int ret;
3146
3147 ret = do_flag_operation(READ_FLAG_OPCODE, STANDARD_RD_REQ, idn, flags_ret);
3148 return ret;
3149 }
3150
3151 /***************************************************************
3152 * do_mode_change
3153 * Description: The function issues the the powermode change to
3154 * UFS device to work using RX and Tx lanes and Gears
3155 * as provided in pwr_mode_params structure.
3156 *
3157 ****************************************************************/
do_mode_change(const struct pwr_mode_params * pmp)3158 int do_mode_change(const struct pwr_mode_params *pmp)
3159 {
3160 send_uic_command(DME_SET, 0x155c0000, 0x0, 0x0); /* PA_TxSkip */
3161 send_uic_command(DME_SET, 0x15680000, 0x0, pmp->tx_gear); /* PA_TxGear */
3162 send_uic_command(DME_SET, 0x15830000, 0x0, pmp->rx_gear); /* PA_RxGear */
3163
3164 if (pmp->pwr_mode == FAST_MODE || pmp->pwr_mode == FASTAUTO_MODE) {
3165 send_uic_command(DME_SET, 0x156a0000, 0x0, pmp->hs_series); /* PA_HSSeries */
3166 send_uic_command(DME_SET, 0x15690000, 0x0, 0x1); /* PA_TxTermination */
3167 send_uic_command(DME_SET, 0x15840000, 0x0, 0x1); /* PA_RxTermination */
3168 send_uic_command(DME_SET, 0x15850000, 0x0, 0x1); /* PA_Scrambling */
3169 } else if (pmp->pwr_mode == SLOW_MODE || pmp->pwr_mode == SLOWAUTO_MODE) {
3170 send_uic_command(DME_SET, 0x15690000, 0x0, 0x0); /* PA_TxTermination */
3171 send_uic_command(DME_SET, 0x15840000, 0x0, 0x0); /* PA_RxTermination */
3172 send_uic_command(DME_SET, 0x15850000, 0x0, 0x0); /* PA_Scrambling */
3173 }
3174
3175 send_uic_command(DME_SET, 0x15600000, 0x0, pmp->tx_lanes); /* PA_ActiveTxDataLanes */
3176 send_uic_command(DME_SET, 0x15800000, 0x0, pmp->rx_lanes); /* PA_ActiveRxDataLanes */
3177
3178 send_uic_command(DME_SET, 0x15b00000, 0x0, 0x1FFF); /* PA_PWRModeUserData0 */
3179 send_uic_command(DME_SET, 0x15b10000, 0x0, 0xFFFF); /* PA_PWRModeUserData1 */
3180 send_uic_command(DME_SET, 0x15b20000, 0x0, 0x7FFF); /* PA_PWRModeUserData2 */
3181 send_uic_command(DME_SET, 0x15b30000, 0x0, 0x1FFF); /* PA_PWRModeUserData3 */
3182 send_uic_command(DME_SET, 0x15b40000, 0x0, 0xFFFF); /* PA_PWRModeUserData4 */
3183 send_uic_command(DME_SET, 0x15b50000, 0x0, 0x7FFF); /* PA_PWRModeUserData5 */
3184 send_uic_command(DME_SET, 0xd0410000, 0x0, 0x1FFF); /* DME_FC0ProtectionTimeOutVal */
3185 send_uic_command(DME_SET, 0xd0420000, 0x0, 0xFFFF); /* DME_TC0ReplayTimeOutVal */
3186 send_uic_command(DME_SET, 0xd0430000, 0x0, 0x7FFF); /* DME_AFC0ReqTimeOutVal */
3187 send_uic_command(DME_SET, 0xd0440000, 0x0, 0x1FFF); /* DME_FC1ProtectionTimeOutVal */
3188 send_uic_command(DME_SET, 0xd0450000, 0x0, 0xFFFF); /* DME_TC1ReplayTimeOutVal */
3189 send_uic_command(DME_SET, 0xd0460000, 0x0, 0x7FFF); /* DME_AFC1ReqTimeOutVal */
3190
3191 /* VS_DebugCounter0Mask */
3192 send_uic_command(DME_SET, 0xd09a0000, 0x0, 0x80000000);
3193 /* VS_DebugCounter1Mask */
3194 send_uic_command(DME_SET, 0xd09b0000, 0x0, 0x78000000);
3195 send_uic_command(DME_SET, 0x15710000, 0x0, pmp->pwr_mode); /* PA_PWRMode */
3196
3197 return 0;
3198 }
3199
adapt_pll_to_power_mode(enum POWER_MODE pwrmode,uint8_t gear,uint8_t rate)3200 void adapt_pll_to_power_mode(enum POWER_MODE pwrmode, uint8_t gear, uint8_t rate)
3201 {
3202 if (pwrmode == FAST_MODE || pwrmode == FASTAUTO_MODE) {
3203 if (gear == 1) { /* hs-g1 */
3204 if (rate == 2) { /* 2: rateb */
3205 send_uic_command(DME_SET, attr_mcb(RG_PLL_PRE_DIV), 0x0, 0x0);
3206 send_uic_command(DME_SET, attr_mcb(RG_PLL_SWC_EN), 0x0, 0x0);
3207 send_uic_command(DME_SET, attr_mcb(RG_PLL_FBK_S), 0x0, 0x01);
3208 send_uic_command(DME_SET, attr_mcb(RG_PLL_FBK_P), 0x0, 0x4c);
3209 }
3210 send_uic_command(DME_SET, attr_mcb(RG_PLL_TXHSGR), 0x0, 0x02);
3211 send_uic_command(DME_SET, attr_mcb(RG_PLL_RXHSGR), 0x0, 0x02);
3212 } else if (gear == 2) { /* hs-g2 */
3213 send_uic_command(DME_SET, attr_mcb(RG_PLL_TXHSGR), 0x0, 0x01);
3214 send_uic_command(DME_SET, attr_mcb(RG_PLL_RXHSGR), 0x0, 0x01);
3215 } else if (gear == 3) { /* hs-g3 */
3216 send_uic_command(DME_SET, attr_mcb(RG_PLL_TXHSGR), 0x0, 0x0);
3217 send_uic_command(DME_SET, attr_mcb(RG_PLL_RXHSGR), 0x0, 0x0);
3218 }
3219 }
3220
3221 /* the PWM's clk is been derived from the pll above */
3222 if (pwrmode == SLOW_MODE || pwrmode == SLOWAUTO_MODE) {
3223 if (gear == 1) { /* pwm-g1 */
3224 send_uic_command(DME_SET, attr_mcb(RG_PLL_TXLSGR), 0x0, 0x07);
3225 send_uic_command(DME_SET, attr_mcb(RG_PLL_RXLSGR), 0x0, 0x06);
3226 } else if (gear == 2) { /* pwm-g2 */
3227 send_uic_command(DME_SET, attr_mcb(RG_PLL_TXLSGR), 0x0, 0x06);
3228 send_uic_command(DME_SET, attr_mcb(RG_PLL_RXLSGR), 0x0, 0x05);
3229 } else if (gear == 3) { /* pwm-g3 */
3230 send_uic_command(DME_SET, attr_mcb(RG_PLL_TXLSGR), 0x0, 0x05);
3231 send_uic_command(DME_SET, attr_mcb(RG_PLL_RXLSGR), 0x0, 0x04);
3232 } else if (gear == 4) { /* pwm-g4 */
3233 send_uic_command(DME_SET, attr_mcb(RG_PLL_TXLSGR), 0x0, 0x04);
3234 send_uic_command(DME_SET, attr_mcb(RG_PLL_RXLSGR), 0x0, 0x03);
3235 }
3236 }
3237 }
3238
change_power_mode(enum POWER_MODE pwrmode,uint8_t gear,uint8_t rate,uint8_t lane)3239 static int change_power_mode(enum POWER_MODE pwrmode, uint8_t gear, uint8_t rate, uint8_t lane)
3240 {
3241 struct pwr_mode_params pmp;
3242 uint32_t value;
3243 int retry = 1000; /* retry 1000 times */
3244 int index = find_device_index();
3245 int ret;
3246
3247 printf("UFS %s Gear-%d Rate-%c Lane-%d\n",
3248 ((pwrmode == SLOW_MODE) ? "Slow" :
3249 ((pwrmode == SLOWAUTO_MODE) ? "SlowAuto" :
3250 ((pwrmode == FAST_MODE) ? "Fast" : "FastAuto"))),
3251 gear, (rate == 1) ? 'A' : 'B', lane);
3252
3253 pmp.tx_gear = gear;
3254 pmp.rx_gear = gear;
3255 pmp.hs_series = rate;
3256
3257 if (lane == 1) {
3258 g_tx_lane_num[index] = 1;
3259 g_rx_lane_num[index] = 1;
3260 } else {
3261 /* PA_ConnectedTxDataLanes */
3262 g_tx_lane_num[index] = (uint8_t)uic_cmd_read(0x1, 0x15610000);
3263
3264 /* PA_ConnectedRxDataLanes */
3265 g_rx_lane_num[index] = (uint8_t)uic_cmd_read(0x1, 0x15810000);
3266
3267 printf("UFS connected lanes Tx-%d Rx-%d\n", g_tx_lane_num[index], g_rx_lane_num[index]);
3268 }
3269
3270 pmp.tx_lanes = g_tx_lane_num[index];
3271 pmp.rx_lanes = g_rx_lane_num[index];
3272 pmp.pwr_mode = pwrmode;
3273
3274 adapt_mode_change(&pmp);
3275 adapt_pll_to_power_mode(pwrmode, gear, rate);
3276
3277 ret = do_mode_change(&pmp);
3278 if (ret)
3279 return ret;
3280
3281 while (--retry) {
3282 value = dwc_ufs_read_reg(UFS_IS_OFF);
3283 if (value & UFS_IS_UPMS_BIT) {
3284 dwc_ufs_write_reg(UFS_IS_OFF, UFS_IS_UPMS_BIT);
3285 break;
3286 }
3287 ufs_waitms(1);
3288 }
3289 value = dwc_ufs_read_reg(UFS_HCS_OFF);
3290 if (((value & UFS_HCS_UPMCRS_MASK) >> UFS_HCS_UPMCRS_OFF) != 0x1) {
3291 printf("check HCS.UPMCRS error, HCS = 0x%x\n", value);
3292 return -1;
3293 }
3294
3295 /* set 0xc4 to 0x80 after mode changes */
3296 /* RX_ERR_STATUS */
3297 send_uic_command(DME_SET, 0x00c40004, 0x0, 0x80);
3298 send_uic_command(DME_SET, 0x00c50004, 0x0, 0x01);
3299 /* RX_ERR_STATUS */
3300 send_uic_command(DME_SET, 0x00c40005, 0x0, 0x80);
3301 send_uic_command(DME_SET, 0x00c50005, 0x0, 0x01);
3302 return UFS_OK;
3303 }
3304
ufs_init(enum POWER_MODE mode,int hs_gear,int rate,int lane)3305 static int ufs_init(enum POWER_MODE mode, int hs_gear, int rate, int lane)
3306 {
3307 int ret;
3308
3309 get_local_dwc_host();
3310
3311 if (dwc_host->is_init)
3312 return 0;
3313
3314 ufs_hardware_init();
3315
3316 ret = ufs_host_init();
3317 if (ret) {
3318 printf("ufs host init fail. ret: %d\n", ret);
3319 return ret;
3320 }
3321
3322 ret = ufs_device_init();
3323 if (ret) {
3324 printf("ufs device init fail. ret: %d\n", ret);
3325 return ret;
3326 }
3327
3328 ret = ufs_get_device_info();
3329 if (ret) {
3330 printf("ufs get device info fail. ret: %d\n", ret);
3331 return ret;
3332 }
3333
3334 ret = ufs_lu_init();
3335 if (ret) {
3336 printf("ufs lu init fail. ret: %d\n", ret);
3337 return ret;
3338 }
3339
3340 ret = ufs_set_ref_clk();
3341 if (ret) {
3342 printf("ufs set ref clk fail. ret: %d\n", ret);
3343 return ret;
3344 }
3345
3346 ret = change_power_mode(mode, hs_gear, rate, lane);
3347 if (ret) {
3348 printf("ufs change mode fail. ret: %d\n", ret);
3349 return ret;
3350 }
3351
3352 ret = ufs_set_active_lun(DEFAULT_ACTIVE_LUN);
3353 if (ret) {
3354 printf("ufs set active lun fail. ret: %d\n", ret);
3355 return ret;
3356 }
3357
3358 ufs_info_init();
3359 dwc_host->is_init = 1;
3360
3361 return ret;
3362 }
3363
ufs_storage_init(void)3364 int ufs_storage_init(void)
3365 {
3366 get_local_dwc_host();
3367
3368 if (ufs_init(DEFAULT_MODE, DEFAULT_GEAR, DEFAULT_RATE, DEFAULT_LANE) != 0) {
3369 /* release resource */
3370 if (dwc_host->mem_pool)
3371 free(dwc_host->mem_pool);
3372 if (dwc_host->wr_buf)
3373 free(dwc_host->wr_buf);
3374
3375 dwc_host->mem_pool = NULL;
3376 dwc_host->wr_buf = NULL;
3377 printf("ufs release memory pool\n");
3378 }
3379
3380 return 0;
3381 }
3382
ufs_reinit(void)3383 void ufs_reinit(void)
3384 {
3385 get_local_dwc_host();
3386
3387 if (dwc_host->mem_pool)
3388 free(dwc_host->mem_pool);
3389 if (dwc_host->wr_buf)
3390 free(dwc_host->wr_buf);
3391
3392 dwc_host->mem_pool = NULL;
3393 dwc_host->wr_buf = NULL;
3394 dwc_host->is_init = 0;
3395
3396 ufs_storage_init();
3397 }
3398
3399