12c3d2faaSYifeng Zhao // SPDX-License-Identifier: GPL-2.0+
22c3d2faaSYifeng Zhao /*
32c3d2faaSYifeng Zhao * Rockchip UFS Host Controller driver
42c3d2faaSYifeng Zhao *
52c3d2faaSYifeng Zhao * Copyright (C) 2024 Rockchip Electronics Co.Ltd.
62c3d2faaSYifeng Zhao */
72c3d2faaSYifeng Zhao
82c3d2faaSYifeng Zhao #include <charset.h>
92c3d2faaSYifeng Zhao #include <common.h>
102c3d2faaSYifeng Zhao #include <dm.h>
112c3d2faaSYifeng Zhao #include <log.h>
122c3d2faaSYifeng Zhao #include <dm/lists.h>
132c3d2faaSYifeng Zhao #include <dm/device-internal.h>
142c3d2faaSYifeng Zhao #include <malloc.h>
152c3d2faaSYifeng Zhao #include <hexdump.h>
162c3d2faaSYifeng Zhao #include <scsi.h>
172c3d2faaSYifeng Zhao #include <asm/io.h>
182c3d2faaSYifeng Zhao #include <asm/dma-mapping.h>
192c3d2faaSYifeng Zhao #include <linux/bitops.h>
202c3d2faaSYifeng Zhao #include <linux/delay.h>
212c3d2faaSYifeng Zhao
222c3d2faaSYifeng Zhao #include "ufs-rockchip-usbplug.h"
232c3d2faaSYifeng Zhao #include "ufs.h"
241e6560dfSYifeng Zhao /* Query request retries */
251e6560dfSYifeng Zhao #define QUERY_REQ_RETRIES 3
261e6560dfSYifeng Zhao /* Query request timeout */
271e6560dfSYifeng Zhao #define QUERY_REQ_TIMEOUT 1500 /* 1.5 seconds */
282c3d2faaSYifeng Zhao
292c3d2faaSYifeng Zhao #if defined(CONFIG_SUPPORT_USBPLUG)
302c3d2faaSYifeng Zhao int _ufs_start(struct ufs_hba *hba);
312c3d2faaSYifeng Zhao
ufs_info_show_dev_desc(void * buf)322c3d2faaSYifeng Zhao static void ufs_info_show_dev_desc(void *buf)
332c3d2faaSYifeng Zhao {
342c3d2faaSYifeng Zhao struct ufs_device_descriptor *dev = (struct ufs_device_descriptor *)buf;
352c3d2faaSYifeng Zhao
362c3d2faaSYifeng Zhao printf("---------------------------\n");
372c3d2faaSYifeng Zhao printf("---UFS Device Descriptor---\n");
382c3d2faaSYifeng Zhao printf("---------------------------\n");
392c3d2faaSYifeng Zhao printf("bLength: 0x%x\n", dev->b_length);
402c3d2faaSYifeng Zhao printf("bDescriptorIDN: 0x%x\n", dev->b_descriptor_idn);
412c3d2faaSYifeng Zhao printf("bDevice: 0x%x\n", dev->b_device);
422c3d2faaSYifeng Zhao printf("bDeviceClass: 0x%x\n", dev->b_device_class);
432c3d2faaSYifeng Zhao printf("bDeviceSubClass: 0x%x\n", dev->b_device_sub_class);
442c3d2faaSYifeng Zhao printf("bProtocol: 0x%x\n", dev->b_protocol);
452c3d2faaSYifeng Zhao printf("bNumberLU: 0x%x\n", dev->b_number_lu);
462c3d2faaSYifeng Zhao printf("bNumberWLU: 0x%x\n", dev->b_number_wlu);
472c3d2faaSYifeng Zhao printf("bBootEnable: 0x%x\n", dev->b_boot_enable);
482c3d2faaSYifeng Zhao printf("bDescrAccessEn: 0x%x\n", dev->b_descr_access_en);
492c3d2faaSYifeng Zhao printf("bInitPowerMode: 0x%x\n", dev->b_init_power_mode);
502c3d2faaSYifeng Zhao printf("bHighPriorityLUN: 0x%x\n", dev->b_high_priority_lun);
512c3d2faaSYifeng Zhao printf("bSecureRemovalType: 0x%x\n", dev->b_secure_removal_type);
522c3d2faaSYifeng Zhao printf("bSecurityLU: 0x%x\n", dev->b_security_lu);
532c3d2faaSYifeng Zhao printf("bBackgroundOpsTermLat: 0x%x\n", dev->b_background_ops_term_lat);
542c3d2faaSYifeng Zhao printf("bInitActiveICCLevel: 0x%x\n", dev->b_init_active_icc_level);
552c3d2faaSYifeng Zhao printf("wSpecVersion: 0x%x\n", to_bigendian16(dev->w_spec_version));
562c3d2faaSYifeng Zhao printf("wManufactureDate: 0x%x\n", to_bigendian16(dev->w_manufacture_date));
572c3d2faaSYifeng Zhao printf("iManufacturerName: 0x%x\n", dev->i_manufacturer_name);
582c3d2faaSYifeng Zhao printf("iProductName: 0x%x\n", dev->i_product_name);
592c3d2faaSYifeng Zhao printf("iSerialNumber: 0x%x\n", dev->i_serial_number);
602c3d2faaSYifeng Zhao printf("iOemID: 0x%x\n", dev->i_oem_id);
612c3d2faaSYifeng Zhao printf("wManufacturerID: 0x%x\n", to_bigendian16(dev->w_manufacturer_id));
622c3d2faaSYifeng Zhao printf("bUD0BaseOffset: 0x%x\n", dev->b_ud_0base_offset);
632c3d2faaSYifeng Zhao printf("bUDConfigPLength: 0x%x\n", dev->b_ud_config_plength);
642c3d2faaSYifeng Zhao printf("bDeviceRTTCap: 0x%x\n", dev->b_device_rtt_cap);
652c3d2faaSYifeng Zhao printf("wPeriodicRTCUpdate: 0x%x\n", to_bigendian16(dev->w_periodic_rtc_update));
662c3d2faaSYifeng Zhao printf("bUFSFeatureSupport: 0x%x\n", dev->b_ufs_feature_support);
672c3d2faaSYifeng Zhao printf("bFFUTimeout: 0x%x\n", dev->b_ffu_timeout);
682c3d2faaSYifeng Zhao printf("bQueueDepth: 0x%x\n", dev->b_queue_depth);
692c3d2faaSYifeng Zhao printf("wDeviceVersion: 0x%x\n", to_bigendian16(dev->w_device_version));
702c3d2faaSYifeng Zhao printf("bNumSecureWPArea: 0x%x\n", dev->b_num_secure_wp_area);
712c3d2faaSYifeng Zhao printf("dPSAMaxDataSize: 0x%x\n", to_bigendian32(dev->d_psa_max_data_size));
722c3d2faaSYifeng Zhao printf("bPSAStateTimeout: 0x%x\n", dev->b_psa_state_timeout);
732c3d2faaSYifeng Zhao printf("iProductRevisionLevel: 0x%x\n", dev->i_product_revision_level);
742c3d2faaSYifeng Zhao }
752c3d2faaSYifeng Zhao
ufs_info_show_conf_desc(void * buf)762c3d2faaSYifeng Zhao static void ufs_info_show_conf_desc(void *buf)
772c3d2faaSYifeng Zhao {
782c3d2faaSYifeng Zhao struct ufs_configuration_descriptor *c_desc = (struct ufs_configuration_descriptor *)buf;
792c3d2faaSYifeng Zhao struct ufs_dev_desc_configuration_param *dev;
802c3d2faaSYifeng Zhao struct ufs_unit_desc_configuration_param *unit;
812c3d2faaSYifeng Zhao int i;
822c3d2faaSYifeng Zhao
832c3d2faaSYifeng Zhao dev = &c_desc->dev_desc_conf_param;
842c3d2faaSYifeng Zhao printf("----------------------------------------\n");
852c3d2faaSYifeng Zhao printf("---UFS Device Descriptor Config Param---\n");
862c3d2faaSYifeng Zhao printf("----------------------------------------\n");
872c3d2faaSYifeng Zhao printf("bLength: 0x%x\n", dev->b_length);
882c3d2faaSYifeng Zhao printf("bDescriptorIDN: 0x%x\n", dev->b_descriptor_idn);
892c3d2faaSYifeng Zhao printf("bConfDescContinue: 0x%x\n", dev->b_conf_desc_continue);
902c3d2faaSYifeng Zhao printf("bBootEnable: 0x%x\n", dev->b_boot_enable);
912c3d2faaSYifeng Zhao printf("bDescrAccessEn: 0x%x\n", dev->b_descr_access_en);
922c3d2faaSYifeng Zhao printf("bInitPowerMode: 0x%x\n", dev->b_init_power_mode);
932c3d2faaSYifeng Zhao printf("bHighPriorityLUN: 0x%x\n", dev->b_high_priority_lun);
942c3d2faaSYifeng Zhao printf("bSecureRemovalType: 0x%x\n", dev->b_secure_removal_type);
952c3d2faaSYifeng Zhao printf("bInitActiveICCLevel: 0x%x\n", dev->b_init_active_icc_level);
962c3d2faaSYifeng Zhao printf("wPeriodicRTCUpdate: 0x%x\n", to_bigendian16(dev->w_periodic_rtc_update));
971865a7e4SYifeng Zhao printf("bSecureRemovalType: 0x%x\n", dev->b_secure_removal_type);
981865a7e4SYifeng Zhao printf("bInitActiveICCLevel: 0x%x\n", dev->b_init_active_icc_level);
991865a7e4SYifeng Zhao printf("wPeriodicRTCUpdate: 0x%x\n", to_bigendian16(dev->w_periodic_rtc_update));
1001865a7e4SYifeng Zhao printf("bWB_EN: 0x%x\n", dev->b_write_booster_buffer_reserve_user_space_en);
1011865a7e4SYifeng Zhao printf("WB_TYPE: 0x%x\n", dev->b_write_booster_buffer_type);
1021865a7e4SYifeng Zhao printf("WB_alloc_units: 0x%x\n", to_bigendian32(dev->d_num_shared_write_booster_buffer_alloc_units));
1032c3d2faaSYifeng Zhao
1042c3d2faaSYifeng Zhao for (i = 0; i < UNIT_DESCS_COUNT; i++) {
1052c3d2faaSYifeng Zhao unit = &c_desc->unit_desc_conf_param[i];
1062c3d2faaSYifeng Zhao
1072c3d2faaSYifeng Zhao printf("-----------------------------------------\n");
1082c3d2faaSYifeng Zhao printf("---UFS Unit %d Descriptor Config Param---\n", i);
1092c3d2faaSYifeng Zhao printf("-----------------------------------------\n");
1102c3d2faaSYifeng Zhao printf("bLUEnable: 0x%x\n", unit->b_lu_enable);
1112c3d2faaSYifeng Zhao printf("bBootLunID: 0x%x\n", unit->b_boot_lun_id);
1122c3d2faaSYifeng Zhao printf("bLUWriteProtect: 0x%x\n", unit->b_lu_write_protect);
1132c3d2faaSYifeng Zhao printf("bMemoryType: 0x%x\n", unit->b_memory_type);
1142c3d2faaSYifeng Zhao printf("dNumAllocUnits: 0x%x\n", to_bigendian32(unit->d_num_alloc_units));
1152c3d2faaSYifeng Zhao printf("bDataReliability: 0x%x\n", unit->b_data_reliability);
1162c3d2faaSYifeng Zhao printf("bLogicalBlockSize: 0x%x\n", unit->b_logical_block_size);
1172c3d2faaSYifeng Zhao printf("bProvisioningType: 0x%x\n", unit->b_provisioning_type);
1182c3d2faaSYifeng Zhao printf("wContextCapabilities: 0x%x\n", to_bigendian16(unit->w_context_capabilities));
1192c3d2faaSYifeng Zhao }
1202c3d2faaSYifeng Zhao }
1212c3d2faaSYifeng Zhao
ufs_get_configuration_desc(struct ufs_hba * hba,struct ufs_configuration_descriptor * c_desc)1222c3d2faaSYifeng Zhao static int ufs_get_configuration_desc(struct ufs_hba *hba, struct ufs_configuration_descriptor *c_desc)
1232c3d2faaSYifeng Zhao {
124*3d58a3e8SYifeng Zhao u8 desc_buf[CONFIGURATION_DESC_V31_LENGTH];
1252c3d2faaSYifeng Zhao u8 *buf = desc_buf;
126*3d58a3e8SYifeng Zhao int length = hba->desc_size.conf_desc;
1272c3d2faaSYifeng Zhao int err;
1282c3d2faaSYifeng Zhao
1292c3d2faaSYifeng Zhao if (CONFIGURATION_DESC_V31_LENGTH == hba->desc_size.conf_desc) {
1302c3d2faaSYifeng Zhao buf = (u8 *)c_desc;
131*3d58a3e8SYifeng Zhao } else if(CONFIGURATION_DESC_V22_LENGTH != hba->desc_size.conf_desc &&
132*3d58a3e8SYifeng Zhao CONFIGURATION_DESC_V30_LENGTH != hba->desc_size.conf_desc) {
1332c3d2faaSYifeng Zhao return -EINVAL;
1342c3d2faaSYifeng Zhao }
1352c3d2faaSYifeng Zhao
1362c3d2faaSYifeng Zhao err = ufshcd_read_desc_param(hba, QUERY_DESC_IDN_CONFIGURATION, 0, 0, buf, length);
1372c3d2faaSYifeng Zhao if (err) {
1382c3d2faaSYifeng Zhao dev_err(hba->dev, "%s: Failed reading configuration Desc. err = %d\n",
1392c3d2faaSYifeng Zhao __func__, err);
1402c3d2faaSYifeng Zhao return err;
1412c3d2faaSYifeng Zhao }
1422c3d2faaSYifeng Zhao
1432c3d2faaSYifeng Zhao if (CONFIGURATION_DESC_V22_LENGTH == hba->desc_size.conf_desc) {
1442c3d2faaSYifeng Zhao memcpy(&c_desc->dev_desc_conf_param, buf, 0x10);
1452c3d2faaSYifeng Zhao buf += 0x10;
1462c3d2faaSYifeng Zhao for (int i = 0; i < UNIT_DESCS_COUNT; i++) {
1472c3d2faaSYifeng Zhao memcpy(&c_desc->unit_desc_conf_param[i], buf, 0x10);
1482c3d2faaSYifeng Zhao buf += 0x10;
1492c3d2faaSYifeng Zhao }
1502c3d2faaSYifeng Zhao }
1512c3d2faaSYifeng Zhao
152*3d58a3e8SYifeng Zhao if (CONFIGURATION_DESC_V30_LENGTH == hba->desc_size.conf_desc) {
153*3d58a3e8SYifeng Zhao memcpy(&c_desc->dev_desc_conf_param, buf, 0x12);
154*3d58a3e8SYifeng Zhao buf += 0x12;
155*3d58a3e8SYifeng Zhao for (int i = 0; i < UNIT_DESCS_COUNT; i++) {
156*3d58a3e8SYifeng Zhao memcpy(&c_desc->unit_desc_conf_param[i], buf, 0x1A);
157*3d58a3e8SYifeng Zhao buf += 0x1A;
158*3d58a3e8SYifeng Zhao }
159*3d58a3e8SYifeng Zhao }
160*3d58a3e8SYifeng Zhao
1612c3d2faaSYifeng Zhao return err;
1622c3d2faaSYifeng Zhao }
1632c3d2faaSYifeng Zhao
ufshcd_write_desc_param(struct ufs_hba * hba,enum desc_idn desc_id,int desc_index,u8 param_offset,u8 * param_read_buf,u8 param_size)1642c3d2faaSYifeng Zhao static int ufshcd_write_desc_param(struct ufs_hba *hba, enum desc_idn desc_id,
1652c3d2faaSYifeng Zhao int desc_index, u8 param_offset, u8 *param_read_buf,
1662c3d2faaSYifeng Zhao u8 param_size)
1672c3d2faaSYifeng Zhao {
1682c3d2faaSYifeng Zhao int ret;
1692c3d2faaSYifeng Zhao u8 *desc_buf;
1702c3d2faaSYifeng Zhao int buff_len;
1712c3d2faaSYifeng Zhao
1722c3d2faaSYifeng Zhao /* Safety check */
1732c3d2faaSYifeng Zhao if (desc_id >= QUERY_DESC_IDN_MAX || !param_size)
1742c3d2faaSYifeng Zhao return -EINVAL;
1752c3d2faaSYifeng Zhao
1762c3d2faaSYifeng Zhao /* Get the max length of descriptor from structure filled up at probe
1772c3d2faaSYifeng Zhao * time.
1782c3d2faaSYifeng Zhao */
1792c3d2faaSYifeng Zhao ret = ufshcd_map_desc_id_to_length(hba, desc_id, &buff_len);
1802c3d2faaSYifeng Zhao
1812c3d2faaSYifeng Zhao /* Sanity checks */
1822c3d2faaSYifeng Zhao if (ret || !buff_len) {
1832c3d2faaSYifeng Zhao dev_err(hba->dev, "%s: Failed to get full descriptor length\n",
1842c3d2faaSYifeng Zhao __func__);
1852c3d2faaSYifeng Zhao return ret;
1862c3d2faaSYifeng Zhao }
1872c3d2faaSYifeng Zhao
1882c3d2faaSYifeng Zhao desc_buf = param_read_buf;
1892c3d2faaSYifeng Zhao /* Request for full descriptor */
1902c3d2faaSYifeng Zhao ret = ufshcd_query_descriptor_retry(hba, UPIU_QUERY_OPCODE_WRITE_DESC,
1912c3d2faaSYifeng Zhao desc_id, desc_index, 0, desc_buf,
1922c3d2faaSYifeng Zhao &buff_len);
1932c3d2faaSYifeng Zhao
1942c3d2faaSYifeng Zhao if (ret)
1952c3d2faaSYifeng Zhao dev_err(hba->dev, "%s: Failed write descriptor. desc_id %d, desc_index %d, param_offset %d, ret %d\n",
1962c3d2faaSYifeng Zhao __func__, desc_id, desc_index, param_offset, ret);
1972c3d2faaSYifeng Zhao
1982c3d2faaSYifeng Zhao return ret;
1992c3d2faaSYifeng Zhao }
2002c3d2faaSYifeng Zhao
ufs_write_configuration_desc(struct ufs_hba * hba,struct ufs_configuration_descriptor * c_desc)2012c3d2faaSYifeng Zhao static int ufs_write_configuration_desc(struct ufs_hba *hba, struct ufs_configuration_descriptor *c_desc)
2022c3d2faaSYifeng Zhao {
203*3d58a3e8SYifeng Zhao u8 desc_buf[CONFIGURATION_DESC_V31_LENGTH];
2042c3d2faaSYifeng Zhao u8 *buf = desc_buf;
205*3d58a3e8SYifeng Zhao int length = hba->desc_size.conf_desc;
2062c3d2faaSYifeng Zhao int err;
2072c3d2faaSYifeng Zhao
2082c3d2faaSYifeng Zhao if (CONFIGURATION_DESC_V31_LENGTH == hba->desc_size.conf_desc) {
2092c3d2faaSYifeng Zhao buf = (u8 *)c_desc;
2102c3d2faaSYifeng Zhao } else if (CONFIGURATION_DESC_V22_LENGTH == hba->desc_size.conf_desc) {
2112c3d2faaSYifeng Zhao memcpy(buf, &c_desc->dev_desc_conf_param, 0x10);
2122c3d2faaSYifeng Zhao buf += 0x10;
2132c3d2faaSYifeng Zhao for (int i = 0; i < UNIT_DESCS_COUNT; i++) {
2142c3d2faaSYifeng Zhao memcpy(buf, &c_desc->unit_desc_conf_param[i], 0x10);
2152c3d2faaSYifeng Zhao buf += 0x10;
2162c3d2faaSYifeng Zhao }
2172c3d2faaSYifeng Zhao buf = desc_buf;
218*3d58a3e8SYifeng Zhao } else if (CONFIGURATION_DESC_V30_LENGTH == hba->desc_size.conf_desc) {
219*3d58a3e8SYifeng Zhao memcpy(buf, &c_desc->dev_desc_conf_param, 0x12);
220*3d58a3e8SYifeng Zhao buf += 0x12;
221*3d58a3e8SYifeng Zhao for (int i = 0; i < UNIT_DESCS_COUNT; i++) {
222*3d58a3e8SYifeng Zhao memcpy(buf, &c_desc->unit_desc_conf_param[i], 0x1A);
223*3d58a3e8SYifeng Zhao buf += 0x1A;
224*3d58a3e8SYifeng Zhao }
225*3d58a3e8SYifeng Zhao buf = desc_buf;
2262c3d2faaSYifeng Zhao } else {
2272c3d2faaSYifeng Zhao return -EINVAL;
2282c3d2faaSYifeng Zhao }
2292c3d2faaSYifeng Zhao
2302c3d2faaSYifeng Zhao err = ufshcd_write_desc_param(hba, QUERY_DESC_IDN_CONFIGURATION, 0, 0, buf, length);
2312c3d2faaSYifeng Zhao if (err) {
2322c3d2faaSYifeng Zhao dev_err(hba->dev, "%s: Failed reading configuration Desc. err = %d\n",
2332c3d2faaSYifeng Zhao __func__, err);
2342c3d2faaSYifeng Zhao return err;
2352c3d2faaSYifeng Zhao }
2362c3d2faaSYifeng Zhao
2372c3d2faaSYifeng Zhao return err;
2382c3d2faaSYifeng Zhao }
2392c3d2faaSYifeng Zhao
ufs_lu_configuration(struct ufs_hba * hba,struct ufs_configuration_descriptor * c_desc)2402c3d2faaSYifeng Zhao static void ufs_lu_configuration(struct ufs_hba *hba, struct ufs_configuration_descriptor *c_desc)
2412c3d2faaSYifeng Zhao {
2422c3d2faaSYifeng Zhao uint32_t denominator = hba->geo_desc->b_allocation_unit_size * to_bigendian32(hba->geo_desc->d_segment_size);
2432c3d2faaSYifeng Zhao struct ufs_dev_desc_configuration_param *dev;
2442c3d2faaSYifeng Zhao struct ufs_unit_desc_configuration_param *unit;
2452c3d2faaSYifeng Zhao uint32_t alloced_units = 0;
2462c3d2faaSYifeng Zhao int i, cap_adj_fac;
2472c3d2faaSYifeng Zhao uint64_t total_raw_device_capacity;
2481865a7e4SYifeng Zhao uint32_t max_wb_alloc_units = cpu_to_be32(hba->geo_desc->d_write_booster_buffer_max_alloc_units);
2491865a7e4SYifeng Zhao uint32_t wb_alloc_units;
2502c3d2faaSYifeng Zhao
2512c3d2faaSYifeng Zhao cap_adj_fac = to_bigendian16(hba->geo_desc->w_enhanced1_cap_adj_fac) / 256;
2522c3d2faaSYifeng Zhao total_raw_device_capacity = cpu_to_be64(hba->geo_desc->q_total_raw_device_capacity);
2532c3d2faaSYifeng Zhao
2542c3d2faaSYifeng Zhao dev = &c_desc->dev_desc_conf_param;
2552c3d2faaSYifeng Zhao dev->b_boot_enable = 0x1;
2562c3d2faaSYifeng Zhao dev->b_descr_access_en = 0x0;
2572c3d2faaSYifeng Zhao dev->b_init_power_mode = 0x1;
2582c3d2faaSYifeng Zhao dev->b_high_priority_lun = 0x7F;
2592c3d2faaSYifeng Zhao dev->b_secure_removal_type = 0x0;
2602c3d2faaSYifeng Zhao dev->b_init_active_icc_level = 0x0;
2612c3d2faaSYifeng Zhao dev->w_periodic_rtc_update = 0x0;
2622c3d2faaSYifeng Zhao
2632c3d2faaSYifeng Zhao unit = &c_desc->unit_desc_conf_param[0];
2642c3d2faaSYifeng Zhao /* lu 1: boot lu A 4MB */
2652c3d2faaSYifeng Zhao unit[1].b_boot_lun_id = WELL_BOOT_LU_A; /* lu 0, boot a */
2662c3d2faaSYifeng Zhao unit[1].b_memory_type = 0x3;
2672c3d2faaSYifeng Zhao unit[1].d_num_alloc_units = (4 * 0x800 * cap_adj_fac + denominator - 1) / denominator;
2682c3d2faaSYifeng Zhao alloced_units += unit[1].d_num_alloc_units;
2692c3d2faaSYifeng Zhao /* lu 2: boot lu B 4MB */
2702c3d2faaSYifeng Zhao unit[2].b_boot_lun_id = WELL_BOOT_LU_B; /* lu 1, boot b */
2712c3d2faaSYifeng Zhao unit[2].b_memory_type = 0x3; /* lu 0, Enhanced Memory */
2722c3d2faaSYifeng Zhao unit[2].d_num_alloc_units = (4 * 0x800 * cap_adj_fac + denominator - 1) / denominator;
2732c3d2faaSYifeng Zhao alloced_units += unit[2].d_num_alloc_units;
2742c3d2faaSYifeng Zhao /* lu 3: data lu 8MB */
2752c3d2faaSYifeng Zhao unit[3].b_boot_lun_id = 0x0; /* lu 2 */
2762c3d2faaSYifeng Zhao unit[3].b_memory_type = 0x3; /* lu 2, Enhanced Memory */
2772c3d2faaSYifeng Zhao unit[3].d_num_alloc_units = (8 * 0x800 * cap_adj_fac + denominator - 1) / denominator;
2782c3d2faaSYifeng Zhao alloced_units += unit[3].d_num_alloc_units;
2791e6560dfSYifeng Zhao
2801865a7e4SYifeng Zhao if (max_wb_alloc_units) {
2811865a7e4SYifeng Zhao wb_alloc_units = max_wb_alloc_units;
2821865a7e4SYifeng Zhao if (wb_alloc_units > max_wb_alloc_units)
2831865a7e4SYifeng Zhao wb_alloc_units = max_wb_alloc_units;
2841865a7e4SYifeng Zhao dev->b_write_booster_buffer_reserve_user_space_en = 1;
2851865a7e4SYifeng Zhao dev->b_write_booster_buffer_type = 1;
2861865a7e4SYifeng Zhao dev->d_num_shared_write_booster_buffer_alloc_units = to_bigendian32(wb_alloc_units);
2871865a7e4SYifeng Zhao }
2881865a7e4SYifeng Zhao
2892c3d2faaSYifeng Zhao /* lu 0: data lu, max capacity*/
2902c3d2faaSYifeng Zhao unit[0].b_boot_lun_id = 0x0; /* lu 3 */
2912c3d2faaSYifeng Zhao unit[0].b_memory_type = 0x0; /* lu 3, Normal Memory */
2922c3d2faaSYifeng Zhao unit[0].d_num_alloc_units = lower_32_bits(total_raw_device_capacity) / denominator - alloced_units;
2932c3d2faaSYifeng Zhao
2942c3d2faaSYifeng Zhao for (i = 0; i <= 3; i++) { /* lu 0 - 3 */
2952c3d2faaSYifeng Zhao unit[i].b_lu_enable = 0x1;
2962c3d2faaSYifeng Zhao unit[i].b_lu_write_protect = 0x0;
2972c3d2faaSYifeng Zhao unit[i].b_data_reliability = 0x1;
2982c3d2faaSYifeng Zhao unit[i].b_logical_block_size = 0x0c;
2992c3d2faaSYifeng Zhao unit[i].b_provisioning_type = 0x2;
3002c3d2faaSYifeng Zhao unit[i].w_context_capabilities = 0x0;
3012c3d2faaSYifeng Zhao unit[i].d_num_alloc_units = to_bigendian32(unit[i].d_num_alloc_units);
3022c3d2faaSYifeng Zhao }
3032c3d2faaSYifeng Zhao }
3042c3d2faaSYifeng Zhao
compair_conf_desp(struct ufs_configuration_descriptor * cda,struct ufs_configuration_descriptor * cdb)3052c3d2faaSYifeng Zhao static int compair_conf_desp(struct ufs_configuration_descriptor *cda, struct ufs_configuration_descriptor *cdb)
3062c3d2faaSYifeng Zhao {
3072c3d2faaSYifeng Zhao struct ufs_dev_desc_configuration_param *dev_a, *dev_b;
3082c3d2faaSYifeng Zhao struct ufs_unit_desc_configuration_param *unit_a, *unit_b;
3092c3d2faaSYifeng Zhao int i, ret;
3102c3d2faaSYifeng Zhao
3112c3d2faaSYifeng Zhao dev_a = &cda->dev_desc_conf_param;
3122c3d2faaSYifeng Zhao dev_b = &cdb->dev_desc_conf_param;
3132c3d2faaSYifeng Zhao
3142c3d2faaSYifeng Zhao if (dev_a->b_boot_enable != dev_b->b_boot_enable)
3152c3d2faaSYifeng Zhao return 0x3;
3162c3d2faaSYifeng Zhao if (dev_a->b_descr_access_en != dev_b->b_descr_access_en)
3172c3d2faaSYifeng Zhao return 0x4;
3182c3d2faaSYifeng Zhao if (dev_a->b_init_power_mode != dev_b->b_init_power_mode)
3192c3d2faaSYifeng Zhao return 0x5;
3202c3d2faaSYifeng Zhao if (dev_a->b_high_priority_lun != dev_b->b_high_priority_lun)
3212c3d2faaSYifeng Zhao return 0x6;
3222c3d2faaSYifeng Zhao if (dev_a->b_secure_removal_type != dev_b->b_secure_removal_type)
3232c3d2faaSYifeng Zhao return 0x7;
3242c3d2faaSYifeng Zhao if (dev_a->b_init_active_icc_level != dev_b->b_init_active_icc_level)
3252c3d2faaSYifeng Zhao return 0x8;
3262c3d2faaSYifeng Zhao if (dev_a->w_periodic_rtc_update != dev_b->w_periodic_rtc_update)
3272c3d2faaSYifeng Zhao return 0x9;
3281865a7e4SYifeng Zhao if (dev_a->b_write_booster_buffer_reserve_user_space_en !=
3291865a7e4SYifeng Zhao dev_b->b_write_booster_buffer_reserve_user_space_en)
3301865a7e4SYifeng Zhao return 0xA;
3311865a7e4SYifeng Zhao if (dev_a->b_write_booster_buffer_type != dev_b->b_write_booster_buffer_type)
3321865a7e4SYifeng Zhao return 0xB;
3331865a7e4SYifeng Zhao if (dev_a->d_num_shared_write_booster_buffer_alloc_units !=
3341865a7e4SYifeng Zhao dev_b->d_num_shared_write_booster_buffer_alloc_units)
3351865a7e4SYifeng Zhao return 0xC;
3362c3d2faaSYifeng Zhao
3372c3d2faaSYifeng Zhao for (i = 0; i < UNIT_DESCS_COUNT; i++) {
3382c3d2faaSYifeng Zhao unit_a = &cda->unit_desc_conf_param[i];
3392c3d2faaSYifeng Zhao unit_b = &cdb->unit_desc_conf_param[i];
3402c3d2faaSYifeng Zhao
3412c3d2faaSYifeng Zhao ret = 0x10 * (i + 1);
3422c3d2faaSYifeng Zhao if (unit_a->b_lu_enable != unit_b->b_lu_enable)
3432c3d2faaSYifeng Zhao return ret;
3442c3d2faaSYifeng Zhao if (unit_a->b_boot_lun_id != unit_b->b_boot_lun_id)
3452c3d2faaSYifeng Zhao return ret + 0x1;
3462c3d2faaSYifeng Zhao if (unit_a->b_lu_write_protect != unit_b->b_lu_write_protect)
3472c3d2faaSYifeng Zhao return ret + 0x2;
3482c3d2faaSYifeng Zhao if (unit_a->b_memory_type != unit_b->b_memory_type)
3492c3d2faaSYifeng Zhao return ret + 0x3;
3502c3d2faaSYifeng Zhao if (unit_a->d_num_alloc_units != unit_b->d_num_alloc_units)
3512c3d2faaSYifeng Zhao return ret + 0x4;
3522c3d2faaSYifeng Zhao if (unit_a->b_data_reliability != unit_b->b_data_reliability)
3532c3d2faaSYifeng Zhao return ret + 0x8;
3542c3d2faaSYifeng Zhao if (unit_a->b_logical_block_size != unit_b->b_logical_block_size)
3552c3d2faaSYifeng Zhao return ret + 0x9;
3562c3d2faaSYifeng Zhao if (unit_a->b_provisioning_type != unit_b->b_provisioning_type)
3572c3d2faaSYifeng Zhao return ret + 0xA;
3582c3d2faaSYifeng Zhao if (unit_a->w_context_capabilities != unit_b->w_context_capabilities)
3592c3d2faaSYifeng Zhao return ret + 0xB;
3602c3d2faaSYifeng Zhao }
3612c3d2faaSYifeng Zhao return 0;
3622c3d2faaSYifeng Zhao }
3632c3d2faaSYifeng Zhao
3642c3d2faaSYifeng Zhao
3651e6560dfSYifeng Zhao /**
3661e6560dfSYifeng Zhao * ufshcd_init_query() - init the query response and request parameters
3671e6560dfSYifeng Zhao */
ufshcd_init_query(struct ufs_hba * hba,struct ufs_query_req ** request,struct ufs_query_res ** response,enum query_opcode opcode,u8 idn,u8 index,u8 selector)3681e6560dfSYifeng Zhao static inline void ufshcd_init_query(struct ufs_hba *hba,
3691e6560dfSYifeng Zhao struct ufs_query_req **request,
3701e6560dfSYifeng Zhao struct ufs_query_res **response,
3711e6560dfSYifeng Zhao enum query_opcode opcode,
3721e6560dfSYifeng Zhao u8 idn, u8 index, u8 selector)
3731e6560dfSYifeng Zhao {
3741e6560dfSYifeng Zhao *request = &hba->dev_cmd.query.request;
3751e6560dfSYifeng Zhao *response = &hba->dev_cmd.query.response;
3761e6560dfSYifeng Zhao memset(*request, 0, sizeof(struct ufs_query_req));
3771e6560dfSYifeng Zhao memset(*response, 0, sizeof(struct ufs_query_res));
3781e6560dfSYifeng Zhao (*request)->upiu_req.opcode = opcode;
3791e6560dfSYifeng Zhao (*request)->upiu_req.idn = idn;
3801e6560dfSYifeng Zhao (*request)->upiu_req.index = index;
3811e6560dfSYifeng Zhao (*request)->upiu_req.selector = selector;
3821e6560dfSYifeng Zhao }
3831e6560dfSYifeng Zhao
3841e6560dfSYifeng Zhao /**
3851e6560dfSYifeng Zhao * ufshcd_query_flag() - API function for sending flag query requests
3861e6560dfSYifeng Zhao */
ufshcd_query_attribute(struct ufs_hba * hba,enum query_opcode opcode,enum attr_id idn,u8 index,u8 selector,u32 * value)3871e6560dfSYifeng Zhao static int ufshcd_query_attribute(struct ufs_hba *hba,enum query_opcode opcode,
3881e6560dfSYifeng Zhao enum attr_id idn, u8 index, u8 selector, u32 *value)
3891e6560dfSYifeng Zhao {
3901e6560dfSYifeng Zhao struct ufs_query_req *request = &hba->dev_cmd.query.request;
3911e6560dfSYifeng Zhao struct ufs_query_res *response = &hba->dev_cmd.query.response;
3921e6560dfSYifeng Zhao int err;
3931e6560dfSYifeng Zhao int timeout = QUERY_REQ_TIMEOUT;
3941e6560dfSYifeng Zhao
3951e6560dfSYifeng Zhao memset(request, 0, sizeof(struct ufs_query_req));
3961e6560dfSYifeng Zhao memset(response, 0, sizeof(struct ufs_query_res));
3971e6560dfSYifeng Zhao request->upiu_req.opcode = opcode;
3981e6560dfSYifeng Zhao request->upiu_req.idn = idn;
3991e6560dfSYifeng Zhao request->upiu_req.index = 0;
4001e6560dfSYifeng Zhao request->upiu_req.selector = 0;
4011e6560dfSYifeng Zhao
4021e6560dfSYifeng Zhao switch (opcode) {
4031e6560dfSYifeng Zhao case UPIU_QUERY_OPCODE_WRITE_ATTR:
4041e6560dfSYifeng Zhao request->query_func = UPIU_QUERY_FUNC_STANDARD_WRITE_REQUEST;
4051e6560dfSYifeng Zhao request->upiu_req.value = be32_to_cpu(*value);
4061e6560dfSYifeng Zhao break;
4071e6560dfSYifeng Zhao case UPIU_QUERY_OPCODE_READ_ATTR:
4081e6560dfSYifeng Zhao request->query_func = UPIU_QUERY_FUNC_STANDARD_READ_REQUEST;
4091e6560dfSYifeng Zhao break;
4101e6560dfSYifeng Zhao default:
4111e6560dfSYifeng Zhao dev_err(hba->dev,
4121e6560dfSYifeng Zhao "%s: Expected query flag opcode but got = %d\n",
4131e6560dfSYifeng Zhao __func__, opcode);
4141e6560dfSYifeng Zhao err = -EINVAL;
4151e6560dfSYifeng Zhao goto out;
4161e6560dfSYifeng Zhao }
4171e6560dfSYifeng Zhao
4181e6560dfSYifeng Zhao err = ufshcd_exec_dev_cmd(hba, DEV_CMD_TYPE_QUERY, timeout);
4191e6560dfSYifeng Zhao
4201e6560dfSYifeng Zhao if (err) {
4211e6560dfSYifeng Zhao dev_err(hba->dev,
4221e6560dfSYifeng Zhao "%s: Sending flag query for idn %d failed, err = %d\n",
4231e6560dfSYifeng Zhao __func__, idn, err);
4241e6560dfSYifeng Zhao goto out;
4251e6560dfSYifeng Zhao }
4261e6560dfSYifeng Zhao
4271e6560dfSYifeng Zhao if (value)
4281e6560dfSYifeng Zhao *value = be32_to_cpu(response->upiu_res.value);
4291e6560dfSYifeng Zhao
4301e6560dfSYifeng Zhao out:
4311e6560dfSYifeng Zhao return err;
4321e6560dfSYifeng Zhao }
4331e6560dfSYifeng Zhao
ufshcd_query_attribute_retry(struct ufs_hba * hba,enum query_opcode opcode,enum attr_id idn,u8 index,u8 selector,u32 * value)4341e6560dfSYifeng Zhao static int ufshcd_query_attribute_retry(struct ufs_hba *hba, enum query_opcode opcode,
4351e6560dfSYifeng Zhao enum attr_id idn, u8 index, u8 selector, u32 *value)
4361e6560dfSYifeng Zhao {
4371e6560dfSYifeng Zhao int ret;
4381e6560dfSYifeng Zhao int retries;
4391e6560dfSYifeng Zhao
4401e6560dfSYifeng Zhao for (retries = 0; retries < QUERY_REQ_RETRIES; retries++) {
4411e6560dfSYifeng Zhao ret = ufshcd_query_attribute(hba, opcode, idn, index, selector, value);
4421e6560dfSYifeng Zhao if (ret)
4431e6560dfSYifeng Zhao dev_dbg(hba->dev,
4441e6560dfSYifeng Zhao "%s: failed with error %d, retries %d\n",
4451e6560dfSYifeng Zhao __func__, ret, retries);
4461e6560dfSYifeng Zhao else
4471e6560dfSYifeng Zhao break;
4481e6560dfSYifeng Zhao }
4491e6560dfSYifeng Zhao
4501e6560dfSYifeng Zhao if (ret)
4511e6560dfSYifeng Zhao dev_err(hba->dev,
4521e6560dfSYifeng Zhao "%s: query attribute, opcode %d, idn %d, failed with error %d after %d retires\n",
4531e6560dfSYifeng Zhao __func__, opcode, idn, ret, retries);
4542c3d2faaSYifeng Zhao return ret;
4552c3d2faaSYifeng Zhao }
4562c3d2faaSYifeng Zhao
read_attribute(struct ufs_hba * hba,enum attr_id idn,u8 index,u8 selector,u32 * value)4571e6560dfSYifeng Zhao static int read_attribute(struct ufs_hba *hba, enum attr_id idn, u8 index, u8 selector, u32 *value)
4582c3d2faaSYifeng Zhao {
4591e6560dfSYifeng Zhao int ret;
4602c3d2faaSYifeng Zhao
4611e6560dfSYifeng Zhao ret = ufshcd_query_attribute_retry(hba, UPIU_QUERY_OPCODE_READ_ATTR,
4621e6560dfSYifeng Zhao idn, index, 0, value);
4631e6560dfSYifeng Zhao return ret;
4641e6560dfSYifeng Zhao }
4651e6560dfSYifeng Zhao
write_attribute(struct ufs_hba * hba,enum attr_id idn,u8 index,u8 selector,u32 * value)4661e6560dfSYifeng Zhao static int write_attribute(struct ufs_hba *hba, enum attr_id idn, u8 index, u8 selector, u32 *value)
4671e6560dfSYifeng Zhao {
4681e6560dfSYifeng Zhao int ret;
4691e6560dfSYifeng Zhao
4701e6560dfSYifeng Zhao ret = ufshcd_query_attribute_retry(hba, UPIU_QUERY_OPCODE_WRITE_ATTR,
4711e6560dfSYifeng Zhao idn, index, 0, value);
4722c3d2faaSYifeng Zhao return ret;
4732c3d2faaSYifeng Zhao }
4742c3d2faaSYifeng Zhao
set_boot_lu_enable(struct ufs_hba * hba)4752c3d2faaSYifeng Zhao static int set_boot_lu_enable(struct ufs_hba *hba)
4762c3d2faaSYifeng Zhao {
4772c3d2faaSYifeng Zhao uint32_t value = 0;
4782c3d2faaSYifeng Zhao uint32_t target_value = DEFAULT_BOOT_LUN;
4792c3d2faaSYifeng Zhao int ret;
4802c3d2faaSYifeng Zhao
4812c3d2faaSYifeng Zhao ret = read_attribute(hba, B_BOOT_LUNEN, 0, 0, &value);
4822c3d2faaSYifeng Zhao if (ret) {
4832c3d2faaSYifeng Zhao printf("read bBootLunEn fail. ret = %d\n", ret);
4842c3d2faaSYifeng Zhao return ret;
4852c3d2faaSYifeng Zhao }
4862c3d2faaSYifeng Zhao
4872c3d2faaSYifeng Zhao if (value != 0)
4881e6560dfSYifeng Zhao printf("UFS get boot W-LU-%c\n", (value == WELL_BOOT_LU_A) ? 'A' : 'B');
4892c3d2faaSYifeng Zhao
4902c3d2faaSYifeng Zhao if (value == target_value)
4912c3d2faaSYifeng Zhao return 0;
4922c3d2faaSYifeng Zhao
4932c3d2faaSYifeng Zhao /* set default boot from Boot LU A */
4942c3d2faaSYifeng Zhao value = target_value;
4952c3d2faaSYifeng Zhao ret = write_attribute(hba, B_BOOT_LUNEN, 0, 0, &value);
4962c3d2faaSYifeng Zhao if (ret) {
4972c3d2faaSYifeng Zhao printf("write bBootLunEn attribute fail. ret = %d\n", ret);
4982c3d2faaSYifeng Zhao return ret;
4992c3d2faaSYifeng Zhao }
5002c3d2faaSYifeng Zhao
5011e6560dfSYifeng Zhao ret = read_attribute(hba, B_BOOT_LUNEN, 0, 0, &value);
5021e6560dfSYifeng Zhao if (ret) {
5031e6560dfSYifeng Zhao printf("read bBootLunEn fail. ret = %d\n", ret);
5042c3d2faaSYifeng Zhao return ret;
5052c3d2faaSYifeng Zhao }
5062c3d2faaSYifeng Zhao
5071e6560dfSYifeng Zhao if (target_value == value)
5081e6560dfSYifeng Zhao return 0;
5091e6560dfSYifeng Zhao
5101e6560dfSYifeng Zhao printf("UFS set boot W-LU(%c) Fail value = %x\n", (value == WELL_BOOT_LU_A) ? 'A' : 'B', value);
5111e6560dfSYifeng Zhao return 0;
5121e6560dfSYifeng Zhao }
5131e6560dfSYifeng Zhao
ufs_set_ref_clk(struct ufs_hba * hba)5141e6560dfSYifeng Zhao static int ufs_set_ref_clk(struct ufs_hba *hba)
5151e6560dfSYifeng Zhao {
5161e6560dfSYifeng Zhao uint32_t value;
5171e6560dfSYifeng Zhao int ret;
5181e6560dfSYifeng Zhao uint32_t target_ref_clk;
5191e6560dfSYifeng Zhao
5201e6560dfSYifeng Zhao target_ref_clk = 1; /* 26 MHz */
5211e6560dfSYifeng Zhao
5221e6560dfSYifeng Zhao ret = read_attribute(hba, B_REFCLK_FREQ, 0, 0, &value);
5231e6560dfSYifeng Zhao if (ret) {
5241e6560dfSYifeng Zhao printf("read bRefClkFreq fail. ret = %d\n", ret);
5251e6560dfSYifeng Zhao return ret;
5261e6560dfSYifeng Zhao }
5271e6560dfSYifeng Zhao
5281e6560dfSYifeng Zhao printf("UFS get ref clock %d Mhz\n", (value == 1) ? 26 : 19);
5291e6560dfSYifeng Zhao if (target_ref_clk == value)
5301e6560dfSYifeng Zhao return 0;
5311e6560dfSYifeng Zhao
5321e6560dfSYifeng Zhao /* set default boot from Boot LU A */
5331e6560dfSYifeng Zhao ret = write_attribute(hba, B_REFCLK_FREQ, 0, 0, &target_ref_clk);
5341e6560dfSYifeng Zhao if (ret) {
5351e6560dfSYifeng Zhao printf("write bRefClkFreq attribute fail. ret = %d\n", ret);
5361e6560dfSYifeng Zhao return ret;
5371e6560dfSYifeng Zhao }
5381e6560dfSYifeng Zhao
5391e6560dfSYifeng Zhao ret = read_attribute(hba, B_REFCLK_FREQ, 0, 0, &value);
5401e6560dfSYifeng Zhao if (ret) {
5411e6560dfSYifeng Zhao printf("read bRefClkFreq fail. ret = %d\n", ret);
5421e6560dfSYifeng Zhao return ret;
5431e6560dfSYifeng Zhao }
5441e6560dfSYifeng Zhao
5451e6560dfSYifeng Zhao if (target_ref_clk == value)
5461e6560dfSYifeng Zhao return 0;
5471e6560dfSYifeng Zhao
5481e6560dfSYifeng Zhao printf("UFS set bRefClkFreq 26Mhz Fail\n");
5491e6560dfSYifeng Zhao return -EINVAL;
5501e6560dfSYifeng Zhao }
5511e6560dfSYifeng Zhao
ufs_create_partition_inventory(struct ufs_hba * hba)5522c3d2faaSYifeng Zhao int ufs_create_partition_inventory(struct ufs_hba *hba)
5532c3d2faaSYifeng Zhao {
5542c3d2faaSYifeng Zhao int err, length;
5552c3d2faaSYifeng Zhao
5562c3d2faaSYifeng Zhao length = (int)sizeof(struct ufs_geometry_descriptor);
5572c3d2faaSYifeng Zhao if (length > hba->desc_size.geom_desc)
5582c3d2faaSYifeng Zhao length = hba->desc_size.geom_desc;
5592c3d2faaSYifeng Zhao err = ufshcd_read_desc_param(hba, QUERY_DESC_IDN_GEOMETRY, 0, 0, (u8 *)hba->geo_desc, length);
5602c3d2faaSYifeng Zhao if (err) {
5612c3d2faaSYifeng Zhao dev_err(hba->dev, "%s: Failed reading geometry Desc. err = %d\n", __func__, err);
5622c3d2faaSYifeng Zhao return err;
5632c3d2faaSYifeng Zhao }
5642c3d2faaSYifeng Zhao
5651865a7e4SYifeng Zhao dev_err(hba->dev, "%s: WB_max_alloc_units = %x\n", __func__,
5661865a7e4SYifeng Zhao hba->geo_desc->d_write_booster_buffer_max_alloc_units);
5671865a7e4SYifeng Zhao
5682c3d2faaSYifeng Zhao err = ufs_get_configuration_desc(hba, hba->rc_desc);
5692c3d2faaSYifeng Zhao if (err) {
5702c3d2faaSYifeng Zhao dev_err(hba->dev, "%s: Failed getting conf info. err = %d\n", __func__, err);
5712c3d2faaSYifeng Zhao return err;
5722c3d2faaSYifeng Zhao }
5732c3d2faaSYifeng Zhao ufs_info_show_conf_desc(hba->rc_desc);
5742c3d2faaSYifeng Zhao
5752c3d2faaSYifeng Zhao memset(hba->wc_desc, 0, sizeof(struct ufs_configuration_descriptor));
5762c3d2faaSYifeng Zhao hba->wc_desc->dev_desc_conf_param.b_length = hba->rc_desc->dev_desc_conf_param.b_length;
5772c3d2faaSYifeng Zhao hba->wc_desc->dev_desc_conf_param.b_descriptor_idn = hba->rc_desc->dev_desc_conf_param.b_descriptor_idn;
5782c3d2faaSYifeng Zhao ufs_lu_configuration(hba, hba->wc_desc);
5792c3d2faaSYifeng Zhao ufs_info_show_conf_desc(hba->wc_desc);
5802c3d2faaSYifeng Zhao
5812c3d2faaSYifeng Zhao err = compair_conf_desp(hba->wc_desc, hba->rc_desc);
5822c3d2faaSYifeng Zhao printf("compair_conf_desp: 0x%x\n", err);
5832c3d2faaSYifeng Zhao
5842c3d2faaSYifeng Zhao if (!err)
5851e6560dfSYifeng Zhao goto out;
5862c3d2faaSYifeng Zhao
5872c3d2faaSYifeng Zhao err = ufs_write_configuration_desc(hba, hba->wc_desc);
5882c3d2faaSYifeng Zhao if (err)
5892c3d2faaSYifeng Zhao dev_err(hba->dev, "%s: Failed write conf info. err = %d\n", __func__, err);
5902c3d2faaSYifeng Zhao
5912c3d2faaSYifeng Zhao err = _ufs_start(hba);
5922c3d2faaSYifeng Zhao if (err)
5932c3d2faaSYifeng Zhao return err;
5941e6560dfSYifeng Zhao out:
5952c3d2faaSYifeng Zhao ufs_info_show_dev_desc(hba->dev_desc);
5962c3d2faaSYifeng Zhao
5971e6560dfSYifeng Zhao ufs_set_ref_clk(hba);
5981e6560dfSYifeng Zhao
5992c3d2faaSYifeng Zhao return set_boot_lu_enable(hba);
6002c3d2faaSYifeng Zhao }
6012c3d2faaSYifeng Zhao #endif
602