summaryrefslogtreecommitdiff
path: root/components
diff options
context:
space:
mode:
authorGUI <[email protected]>2026-08-07 16:54:29 +0800
committerGitHub <[email protected]>2026-08-07 16:54:29 +0800
commit19e9be8779eb09d240bacbeee8c1c245fd874832 (patch)
tree5b13a43c96e47937b22b8f1a8751c991336b5462 /components
parentabc2c59e57c919b51e46b8dedc3a07dc14fd3911 (diff)
[dm][ufs] fixup the ufs supported (#11646)
* [dm][block] add 4K support for EFI partion Signed-off-by: GuEe-GUI <[email protected]> * [dm][ufs] fixup the linkup flow Signed-off-by: GuEe-GUI <[email protected]> * style: format code with clang-format * style: format complete changed files with clang-format * drivers: address UFS review feedback --------- Signed-off-by: GuEe-GUI <[email protected]>
Diffstat (limited to 'components')
-rw-r--r--components/drivers/block/partitions/efi.c279
-rwxr-xr-xcomponents/drivers/include/drivers/ufs.h583
-rwxr-xr-xcomponents/drivers/ufs/ufs.c395
-rwxr-xr-xcomponents/drivers/ufs/ufs_pm.c48
4 files changed, 779 insertions, 526 deletions
diff --git a/components/drivers/block/partitions/efi.c b/components/drivers/block/partitions/efi.c
index 22f6ba1659..58c68cc98b 100644
--- a/components/drivers/block/partitions/efi.c
+++ b/components/drivers/block/partitions/efi.c
@@ -93,8 +93,8 @@ rt_inline int pmbr_part_valid(gpt_mbr_record *part)
*/
static int is_pmbr_valid(legacy_mbr *mbr, rt_size_t total_sectors)
{
- rt_uint32_t sz = 0;
- int part = 0, ret = 0; /* invalid by default */
+ rt_uint32_t sz = 0;
+ int part = 0, ret = 0; /* invalid by default */
if (!mbr || rt_le16_to_cpu(mbr->signature) != MSDOS_MBR_SIGNATURE)
{
@@ -151,7 +151,7 @@ _check_hybrid:
if (sz != (rt_uint32_t)total_sectors - 1 && sz != 0xffffffff)
{
LOG_W("GPT: mbr size in lba (%u) different than whole disk (%u)",
- sz, rt_min_t(rt_uint32_t, total_sectors - 1, 0xffffffff));
+ sz, rt_min_t(rt_uint32_t, total_sectors - 1, 0xffffffff));
}
}
@@ -169,31 +169,108 @@ _done:
* @return number of bytes read on success, 0 on error.
*/
static rt_size_t read_lba(struct rt_blk_disk *disk,
- rt_uint64_t lba, rt_uint8_t *buffer, rt_size_t count)
+ rt_uint64_t lba, rt_uint8_t *buffer, rt_size_t count)
{
- rt_size_t totalreadcount = 0;
+ rt_uint32_t lbs;
+ rt_ssize_t cap_ss, lbs_ss;
+ rt_size_t totalreadcount = 0;
+ rt_uint8_t *secbuf = RT_NULL;
+ rt_uint64_t capacity, disk_bytes, n512;
- if (!buffer || lba > last_lba(disk))
+ if (!buffer || count == 0)
{
return 0;
}
- for (rt_uint64_t n = lba; count; ++n)
+ cap_ss = rt_blk_disk_get_capacity(disk);
+ lbs_ss = rt_blk_disk_get_logical_block_size(disk);
+ if (cap_ss < 0 || lbs_ss < 0)
{
- int copied = 512;
+ return 0;
+ }
+
+ lbs = (rt_uint32_t)lbs_ss;
+ capacity = (rt_uint64_t)cap_ss;
+
+ if (lbs < 512 || (lbs % 512) != 0)
+ {
+ return 0;
+ }
+
+ if (lba >= capacity)
+ {
+ return 0;
+ }
+
+ disk_bytes = capacity * (rt_uint64_t)lbs;
+ n512 = lba * ((rt_uint64_t)lbs / 512);
- disk->ops->read(disk, n, buffer, 1);
+ secbuf = rt_malloc(lbs);
+ if (!secbuf)
+ {
+ return 0;
+ }
+
+ while (count > 0)
+ {
+ int copied = 512;
+ rt_ssize_t rd;
+ rt_uint32_t off;
+ rt_uint64_t log_sec, byte_off = n512 * 512;
+
+ if (byte_off >= disk_bytes)
+ {
+ break;
+ }
+
+ if (copied > (int)count)
+ {
+ copied = (int)count;
+ }
- if (copied > count)
+ if ((rt_uint64_t)copied > disk_bytes - byte_off)
{
- copied = count;
+ copied = (int)(disk_bytes - byte_off);
}
- buffer += copied;
+ log_sec = byte_off / lbs;
+ off = (rt_uint32_t)(byte_off % lbs);
+
+ if (off + (rt_uint32_t)copied <= lbs)
+ {
+ rd = disk->ops->read(disk, (rt_off_t)log_sec, secbuf, 1);
+ if (rd != 1)
+ {
+ break;
+ }
+ rt_memcpy(buffer, secbuf + off, copied);
+ }
+ else
+ {
+ rt_uint32_t first = lbs - off;
+
+ rd = disk->ops->read(disk, (rt_off_t)log_sec, secbuf, 1);
+ if (rd != 1)
+ {
+ break;
+ }
+ rt_memcpy(buffer, secbuf + off, first);
+
+ rd = disk->ops->read(disk, (rt_off_t)(log_sec + 1), secbuf, 1);
+ if (rd != 1)
+ {
+ break;
+ }
+ rt_memcpy(buffer + first, secbuf, copied - first);
+ }
+
+ buffer += copied;
totalreadcount += copied;
- count -= copied;
+ count -= copied;
+ ++n512;
}
+ rt_free(secbuf);
return totalreadcount;
}
@@ -205,10 +282,10 @@ static rt_size_t read_lba(struct rt_blk_disk *disk,
* @return ptes on success, null on error.
*/
static gpt_entry *alloc_read_gpt_entries(struct rt_blk_disk *disk,
- gpt_header *gpt)
+ gpt_header *gpt)
{
- rt_size_t count;
- gpt_entry *pte;
+ rt_size_t count;
+ gpt_entry *pte;
rt_uint64_t entry_lba;
if (!gpt)
@@ -255,7 +332,14 @@ static gpt_entry *alloc_read_gpt_entries(struct rt_blk_disk *disk,
static gpt_header *alloc_read_gpt_header(struct rt_blk_disk *disk, rt_uint64_t lba)
{
gpt_header *gpt;
- rt_uint32_t ssz = rt_blk_disk_get_logical_block_size(disk);
+ rt_uint32_t ssz;
+ rt_ssize_t lbs_ss = rt_blk_disk_get_logical_block_size(disk);
+
+ if (lbs_ss <= 0)
+ {
+ return RT_NULL;
+ }
+ ssz = (rt_uint32_t)lbs_ss;
gpt = rt_malloc(ssz);
@@ -287,11 +371,11 @@ static gpt_header *alloc_read_gpt_header(struct rt_blk_disk *disk, rt_uint64_t l
* If valid, returns pointers to newly allocated GPT header and PTEs.
*/
static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk,
- rt_uint64_t lba, gpt_header **gpt, gpt_entry **ptes)
+ rt_uint64_t lba, gpt_header **gpt, gpt_entry **ptes)
{
rt_uint32_t crc, origcrc;
rt_uint64_t lastlba, pt_size;
- rt_ssize_t logical_block_size;
+ rt_ssize_t logical_block_size;
if (!ptes)
{
@@ -307,22 +391,26 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk,
if (rt_le64_to_cpu((*gpt)->signature) != GPT_HEADER_SIGNATURE)
{
LOG_D("%s: GUID Partition Table Header signature is wrong: %lld != %lld",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu((*gpt)->signature),
- (rt_uint64_t)GPT_HEADER_SIGNATURE);
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu((*gpt)->signature),
+ (rt_uint64_t)GPT_HEADER_SIGNATURE);
goto _fail;
}
/* Check the GUID Partition Table header size is too big */
logical_block_size = rt_blk_disk_get_logical_block_size(disk);
+ if (logical_block_size <= 0)
+ {
+ goto _fail;
+ }
- if (rt_le32_to_cpu((*gpt)->header_size) > logical_block_size)
+ if (rt_le32_to_cpu((*gpt)->header_size) > (rt_uint32_t)logical_block_size)
{
LOG_D("%s: GUID Partition Table Header size is too large: %u > %u",
- to_disk_name(disk),
- rt_le32_to_cpu((*gpt)->header_size),
- logical_block_size);
+ to_disk_name(disk),
+ rt_le32_to_cpu((*gpt)->header_size),
+ (rt_uint32_t)logical_block_size);
goto _fail;
}
@@ -331,22 +419,22 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk,
if (rt_le32_to_cpu((*gpt)->header_size) < sizeof(gpt_header))
{
LOG_D("%s: GUID Partition Table Header size is too small: %u < %u",
- to_disk_name(disk),
- rt_le32_to_cpu((*gpt)->header_size),
- sizeof(gpt_header));
+ to_disk_name(disk),
+ rt_le32_to_cpu((*gpt)->header_size),
+ sizeof(gpt_header));
goto _fail;
}
/* Check the GUID Partition Table CRC */
- origcrc = rt_le32_to_cpu((*gpt)->header_crc32);
+ origcrc = rt_le32_to_cpu((*gpt)->header_crc32);
(*gpt)->header_crc32 = 0;
- crc = efi_crc32((const rt_uint8_t *)(*gpt), rt_le32_to_cpu((*gpt)->header_size));
+ crc = efi_crc32((const rt_uint8_t *)(*gpt), rt_le32_to_cpu((*gpt)->header_size));
if (crc != origcrc)
{
LOG_D("%s: GUID Partition Table Header CRC is wrong: %x != %x",
- to_disk_name(disk), crc, origcrc);
+ to_disk_name(disk), crc, origcrc);
goto _fail;
}
@@ -360,9 +448,9 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk,
if (rt_le64_to_cpu((*gpt)->start_lba) != lba)
{
LOG_D("%s: GPT start_lba incorrect: %lld != %lld",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu((*gpt)->start_lba),
- (rt_uint64_t)lba);
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu((*gpt)->start_lba),
+ (rt_uint64_t)lba);
goto _fail;
}
@@ -373,9 +461,9 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk,
if (rt_le64_to_cpu((*gpt)->first_usable_lba) > lastlba)
{
LOG_D("%s: GPT: first_usable_lba incorrect: %lld > %lld",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu((*gpt)->first_usable_lba),
- (rt_uint64_t)lastlba);
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu((*gpt)->first_usable_lba),
+ (rt_uint64_t)lastlba);
goto _fail;
}
@@ -383,18 +471,18 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk,
if (rt_le64_to_cpu((*gpt)->last_usable_lba) > lastlba)
{
LOG_D("%s: GPT: last_usable_lba incorrect: %lld > %lld",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu((*gpt)->last_usable_lba),
- (rt_uint64_t)lastlba);
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu((*gpt)->last_usable_lba),
+ (rt_uint64_t)lastlba);
goto _fail;
}
if (rt_le64_to_cpu((*gpt)->last_usable_lba) < rt_le64_to_cpu((*gpt)->first_usable_lba))
{
LOG_D("%s: GPT: last_usable_lba incorrect: %lld > %lld",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu((*gpt)->last_usable_lba),
- (rt_uint64_t)rt_le64_to_cpu((*gpt)->first_usable_lba));
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu((*gpt)->last_usable_lba),
+ (rt_uint64_t)rt_le64_to_cpu((*gpt)->first_usable_lba));
goto _fail;
}
@@ -409,7 +497,7 @@ static rt_bool_t is_gpt_valid(struct rt_blk_disk *disk,
/* Sanity check partition table size */
pt_size = (rt_uint64_t)rt_le32_to_cpu((*gpt)->num_partition_entries) *
- rt_le32_to_cpu((*gpt)->sizeof_partition_entry);
+ rt_le32_to_cpu((*gpt)->sizeof_partition_entry);
if (pt_size > (rt_uint64_t)RT_UINT32_MAX)
{
@@ -473,7 +561,7 @@ rt_inline rt_bool_t is_pte_valid(const gpt_entry *pte, const rt_size_t lastlba)
* @param lastlba the last LBA number.
*/
static void compare_gpts(struct rt_blk_disk *disk,
- gpt_header *pgpt, gpt_header *agpt, rt_uint64_t lastlba)
+ gpt_header *pgpt, gpt_header *agpt, rt_uint64_t lastlba)
{
int error_found = 0;
@@ -485,9 +573,9 @@ static void compare_gpts(struct rt_blk_disk *disk,
if (rt_le64_to_cpu(pgpt->start_lba) != rt_le64_to_cpu(agpt->alternate_lba))
{
LOG_W("%s: GPT:Primary header LBA(%lld) != Alt(%lld), header alternate_lba",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu(pgpt->start_lba),
- (rt_uint64_t)rt_le64_to_cpu(agpt->alternate_lba));
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu(pgpt->start_lba),
+ (rt_uint64_t)rt_le64_to_cpu(agpt->alternate_lba));
++error_found;
}
@@ -495,9 +583,9 @@ static void compare_gpts(struct rt_blk_disk *disk,
if (rt_le64_to_cpu(pgpt->alternate_lba) != rt_le64_to_cpu(agpt->start_lba))
{
LOG_W("%s: GPT:Primary header alternate_lba(%lld) != Alt(%lld), header start_lba",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu(pgpt->alternate_lba),
- (rt_uint64_t)rt_le64_to_cpu(agpt->start_lba));
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu(pgpt->alternate_lba),
+ (rt_uint64_t)rt_le64_to_cpu(agpt->start_lba));
++error_found;
}
@@ -505,9 +593,9 @@ static void compare_gpts(struct rt_blk_disk *disk,
if (rt_le64_to_cpu(pgpt->first_usable_lba) != rt_le64_to_cpu(agpt->first_usable_lba))
{
LOG_W("%s: GPT:first_usable_lbas don't match %lld != %lld",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu(pgpt->first_usable_lba),
- (rt_uint64_t)rt_le64_to_cpu(agpt->first_usable_lba));
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu(pgpt->first_usable_lba),
+ (rt_uint64_t)rt_le64_to_cpu(agpt->first_usable_lba));
++error_found;
}
@@ -515,9 +603,9 @@ static void compare_gpts(struct rt_blk_disk *disk,
if (rt_le64_to_cpu(pgpt->last_usable_lba) != rt_le64_to_cpu(agpt->last_usable_lba))
{
LOG_W("%s: GPT:last_usable_lbas don't match %lld != %lld",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu(pgpt->last_usable_lba),
- (rt_uint64_t)rt_le64_to_cpu(agpt->last_usable_lba));
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu(pgpt->last_usable_lba),
+ (rt_uint64_t)rt_le64_to_cpu(agpt->last_usable_lba));
++error_found;
}
@@ -530,34 +618,34 @@ static void compare_gpts(struct rt_blk_disk *disk,
}
if (rt_le32_to_cpu(pgpt->num_partition_entries) !=
- rt_le32_to_cpu(agpt->num_partition_entries))
+ rt_le32_to_cpu(agpt->num_partition_entries))
{
LOG_W("%s: GPT:num_partition_entries don't match: 0x%x != 0x%x",
- to_disk_name(disk),
- rt_le32_to_cpu(pgpt->num_partition_entries),
- rt_le32_to_cpu(agpt->num_partition_entries));
+ to_disk_name(disk),
+ rt_le32_to_cpu(pgpt->num_partition_entries),
+ rt_le32_to_cpu(agpt->num_partition_entries));
++error_found;
}
if (rt_le32_to_cpu(pgpt->sizeof_partition_entry) !=
- rt_le32_to_cpu(agpt->sizeof_partition_entry))
+ rt_le32_to_cpu(agpt->sizeof_partition_entry))
{
LOG_W("%s: GPT:sizeof_partition_entry values don't match: 0x%x != 0x%x",
- to_disk_name(disk),
- rt_le32_to_cpu(pgpt->sizeof_partition_entry),
- rt_le32_to_cpu(agpt->sizeof_partition_entry));
+ to_disk_name(disk),
+ rt_le32_to_cpu(pgpt->sizeof_partition_entry),
+ rt_le32_to_cpu(agpt->sizeof_partition_entry));
++error_found;
}
if (rt_le32_to_cpu(pgpt->partition_entry_array_crc32) !=
- rt_le32_to_cpu(agpt->partition_entry_array_crc32))
+ rt_le32_to_cpu(agpt->partition_entry_array_crc32))
{
LOG_W("%s: GPT:partition_entry_array_crc32 values don't match: 0x%x != 0x%x",
- to_disk_name(disk),
- rt_le32_to_cpu(pgpt->partition_entry_array_crc32),
- rt_le32_to_cpu(agpt->partition_entry_array_crc32));
+ to_disk_name(disk),
+ rt_le32_to_cpu(pgpt->partition_entry_array_crc32),
+ rt_le32_to_cpu(agpt->partition_entry_array_crc32));
++error_found;
}
@@ -565,9 +653,9 @@ static void compare_gpts(struct rt_blk_disk *disk,
if (rt_le64_to_cpu(pgpt->alternate_lba) != lastlba)
{
LOG_W("%s: GPT:Primary header thinks Alt. header is not at the end of the disk: %lld != %lld",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu(pgpt->alternate_lba),
- (rt_uint64_t)lastlba);
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu(pgpt->alternate_lba),
+ (rt_uint64_t)lastlba);
++error_found;
}
@@ -575,9 +663,9 @@ static void compare_gpts(struct rt_blk_disk *disk,
if (rt_le64_to_cpu(agpt->start_lba) != lastlba)
{
LOG_W("%s: GPT:Alternate GPT header not at the end of the disk: %lld != %lld",
- to_disk_name(disk),
- (rt_uint64_t)rt_le64_to_cpu(agpt->start_lba),
- (rt_uint64_t)lastlba);
+ to_disk_name(disk),
+ (rt_uint64_t)rt_le64_to_cpu(agpt->start_lba),
+ (rt_uint64_t)lastlba);
++error_found;
}
@@ -605,20 +693,27 @@ static void compare_gpts(struct rt_blk_disk *disk,
* the user to decide to use the Alternate GPT.
*/
static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk,
- gpt_header **gpt, gpt_entry **ptes)
+ gpt_header **gpt, gpt_entry **ptes)
{
- int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
+ int good_pgpt = 0, good_agpt = 0, good_pmbr = 0;
gpt_header *pgpt = RT_NULL, *agpt = RT_NULL;
- gpt_entry *pptes = RT_NULL, *aptes = RT_NULL;
+ gpt_entry *pptes = RT_NULL, *aptes = RT_NULL;
legacy_mbr *legacymbr;
- rt_size_t total_sectors = rt_blk_disk_get_capacity(disk);
- rt_size_t lastlba;
+ rt_ssize_t cap_ss = rt_blk_disk_get_capacity(disk);
+ rt_size_t total_sectors;
+ rt_size_t lastlba;
if (!ptes)
{
return RT_FALSE;
}
+ if (cap_ss < 0)
+ {
+ return RT_FALSE;
+ }
+ total_sectors = (rt_size_t)cap_ss;
+
lastlba = last_lba(disk);
if (!force_gpt)
@@ -631,7 +726,11 @@ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk,
return RT_FALSE;
}
- read_lba(disk, 0, (rt_uint8_t *)legacymbr, sizeof(*legacymbr));
+ if (read_lba(disk, 0, (rt_uint8_t *)legacymbr, sizeof(*legacymbr)) < sizeof(*legacymbr))
+ {
+ rt_free(legacymbr);
+ return RT_FALSE;
+ }
good_pmbr = is_pmbr_valid(legacymbr, total_sectors);
rt_free(legacymbr);
@@ -641,7 +740,7 @@ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk,
}
LOG_D("%s: Device has a %s MBR", to_disk_name(disk),
- good_pmbr == GPT_MBR_PROTECTIVE ? "protective" : "hybrid");
+ good_pmbr == GPT_MBR_PROTECTIVE ? "protective" : "hybrid");
}
good_pgpt = is_gpt_valid(disk, GPT_PRIMARY_PARTITION_TABLE_LBA, &pgpt, &pptes);
@@ -667,7 +766,7 @@ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk,
/* The good cases */
if (good_pgpt)
{
- *gpt = pgpt;
+ *gpt = pgpt;
*ptes = pptes;
rt_free(agpt);
rt_free(aptes);
@@ -681,7 +780,7 @@ static rt_bool_t find_valid_gpt(struct rt_blk_disk *disk,
}
else if (good_agpt)
{
- *gpt = agpt;
+ *gpt = agpt;
*ptes = aptes;
rt_free(pgpt);
rt_free(pptes);
@@ -697,7 +796,7 @@ _fail:
rt_free(pptes);
rt_free(aptes);
- *gpt = RT_NULL;
+ *gpt = RT_NULL;
*ptes = RT_NULL;
return RT_FALSE;
@@ -706,8 +805,8 @@ _fail:
rt_err_t efi_partition(struct rt_blk_disk *disk)
{
rt_uint32_t entries_nr;
- gpt_header *gpt = RT_NULL;
- gpt_entry *ptes = RT_NULL;
+ gpt_header *gpt = RT_NULL;
+ gpt_entry *ptes = RT_NULL;
if (!find_valid_gpt(disk, &gpt, &ptes) || !gpt || !ptes)
{
@@ -722,8 +821,8 @@ rt_err_t efi_partition(struct rt_blk_disk *disk)
for (int i = 0; i < entries_nr && i < disk->max_partitions; ++i)
{
rt_uint64_t start = rt_le64_to_cpu(ptes[i].starting_lba);
- rt_uint64_t size = rt_le64_to_cpu(ptes[i].ending_lba) -
- rt_le64_to_cpu(ptes[i].starting_lba) + 1ULL;
+ rt_uint64_t size = rt_le64_to_cpu(ptes[i].ending_lba) -
+ rt_le64_to_cpu(ptes[i].starting_lba) + 1ULL;
if (!is_pte_valid(&ptes[i], last_lba(disk)))
{
diff --git a/components/drivers/include/drivers/ufs.h b/components/drivers/include/drivers/ufs.h
index c38de94e4a..f954dabfeb 100755
--- a/components/drivers/include/drivers/ufs.h
+++ b/components/drivers/include/drivers/ufs.h
@@ -18,293 +18,293 @@
#include <drivers/scsi.h>
#include <drivers/byteorder.h>
-#define __BIT_FIELD(v, h, l) ((v & RT_GENMASK(h, l)) >> l)
+#define __BIT_FIELD(v, h, l) ((v & RT_GENMASK(h, l)) >> l)
/* Host Capabilities */
-#define RT_UFS_REG_CAP 0x00 /* Host Controller Capabiities */
-#define RT_UFS_REG_CAP_NUTRS(v) __BIT_FIELD(v, 4, 0) /* Number of UTP Transfer Request Slots */
-#define RT_UFS_REG_CAP_NORTT(v) __BIT_FIELD(v, 15, 8) /* Number of outstanding READY TO TRANSFER requests supported */
-#define RT_UFS_REG_CAP_NUTMRS(v) __BIT_FIELD(v, 18, 16) /* Number of UTP Task Management Request Slots */
-#define RT_UFS_REG_CAP_AUTOH8 RT_BIT(23) /* Auto-Hibernation Support */
-#define RT_UFS_REG_CAP_64AS RT_BIT(24) /* 64-bit addressing supported */
-#define RT_UFS_REG_CAP_OODDS RT_BIT(25) /* Out of order data delivery supported */
-#define RT_UFS_REG_CAP_UICDMETMS RT_BIT(26) /* UIC DME_TEST_MODE command supported */
-#define RT_UFS_REG_CAP_UME RT_BIT(27) /* Reserved for Unified Memory Extension */
-#define RT_UFS_REG_VER 0x08 /* UFS Version */
-#define RT_UFS_REG_VER_VS(v) __BIT_FIELD(v, 03, 0) /* Version Suffix (VS) */
-#define RT_UFS_REG_VER_MNR(v) __BIT_FIELD(v, 07, 4) /* Minor Version Number (MNR) */
-#define RT_UFS_REG_VER_MJR(v) __BIT_FIELD(v, 15, 8) /* Major Version Number (MJR) */
-#define RT_UFS_REG_HCPID 0x10 /* Host Controller Identification Descriptor – Product ID */
-#define RT_UFS_REG_HCMID 0x14 /* Host Controller Identification Descriptor – Manufacturer ID */
-#define RT_UFS_REG_HCMID_MIC(v) __BIT_FIELD(v, 7, 0) /* Manufacturer Identification Code */
-#define RT_UFS_REG_HCMID_BI(v) __BIT_FIELD(v, 15, 8) /* Bank Index */
-#define RT_UFS_REG_AHIT 0x18 /* Auto-Hibernate Idle Timer */
-#define RT_UFS_REG_AHIT_AH8ITV(v) __BIT_FIELD(v, 9, 0) /* Auto-Hibern8 Idle Timer Value */
-#define RT_UFS_REG_AHIT_TS(v) __BIT_FIELD(v, 12, 10) /* Timer scale */
+#define RT_UFS_REG_CAP 0x00 /* Host Controller Capabiities */
+#define RT_UFS_REG_CAP_NUTRS(v) __BIT_FIELD(v, 4, 0) /* Number of UTP Transfer Request Slots */
+#define RT_UFS_REG_CAP_NORTT(v) __BIT_FIELD(v, 15, 8) /* Number of outstanding READY TO TRANSFER requests supported */
+#define RT_UFS_REG_CAP_NUTMRS(v) __BIT_FIELD(v, 18, 16) /* Number of UTP Task Management Request Slots */
+#define RT_UFS_REG_CAP_AUTOH8 RT_BIT(23) /* Auto-Hibernation Support */
+#define RT_UFS_REG_CAP_64AS RT_BIT(24) /* 64-bit addressing supported */
+#define RT_UFS_REG_CAP_OODDS RT_BIT(25) /* Out of order data delivery supported */
+#define RT_UFS_REG_CAP_UICDMETMS RT_BIT(26) /* UIC DME_TEST_MODE command supported */
+#define RT_UFS_REG_CAP_UME RT_BIT(27) /* Reserved for Unified Memory Extension */
+#define RT_UFS_REG_VER 0x08 /* UFS Version */
+#define RT_UFS_REG_VER_VS(v) __BIT_FIELD(v, 03, 0) /* Version Suffix (VS) */
+#define RT_UFS_REG_VER_MNR(v) __BIT_FIELD(v, 07, 4) /* Minor Version Number (MNR) */
+#define RT_UFS_REG_VER_MJR(v) __BIT_FIELD(v, 15, 8) /* Major Version Number (MJR) */
+#define RT_UFS_REG_HCPID 0x10 /* Host Controller Identification Descriptor – Product ID */
+#define RT_UFS_REG_HCMID 0x14 /* Host Controller Identification Descriptor – Manufacturer ID */
+#define RT_UFS_REG_HCMID_MIC(v) __BIT_FIELD(v, 7, 0) /* Manufacturer Identification Code */
+#define RT_UFS_REG_HCMID_BI(v) __BIT_FIELD(v, 15, 8) /* Bank Index */
+#define RT_UFS_REG_AHIT 0x18 /* Auto-Hibernate Idle Timer */
+#define RT_UFS_REG_AHIT_AH8ITV(v) __BIT_FIELD(v, 9, 0) /* Auto-Hibern8 Idle Timer Value */
+#define RT_UFS_REG_AHIT_TS(v) __BIT_FIELD(v, 12, 10) /* Timer scale */
/* Operation and Runtime */
-#define RT_UFS_REG_IS 0x20 /* Interrupt Status */
-#define RT_UFS_REG_IS_UTRCS RT_BIT(0) /* UTP Transfer Request Completion Status */
-#define RT_UFS_REG_IS_UDEPRI RT_BIT(1) /* UIC DME_ENDPOINTRESET Indication */
-#define RT_UFS_REG_IS_UE RT_BIT(2) /* UIC Error */
-#define RT_UFS_REG_IS_UTMS RT_BIT(3) /* UIC Test Mode Status */
-#define RT_UFS_REG_IS_UPMS RT_BIT(4) /* UIC Power Mode Status */
-#define RT_UFS_REG_IS_UHXS RT_BIT(5) /* UIC Hibernate Exit Status */
-#define RT_UFS_REG_IS_UHES RT_BIT(6) /* UIC Hibernate Enter Status */
-#define RT_UFS_REG_IS_ULLS RT_BIT(7) /* UIC Link Lost Status */
-#define RT_UFS_REG_IS_ULSS RT_BIT(8) /* UIC Link Startup Status */
-#define RT_UFS_REG_IS_UTMRCS RT_BIT(9) /* UTP Task Management Request Completion Status */
-#define RT_UFS_REG_IS_UCCS RT_BIT(10) /* UIC Command Completion Status */
-#define RT_UFS_REG_IS_DFES RT_BIT(11) /* Device Fatal Error Status */
-#define RT_UFS_REG_IS_UTPES RT_BIT(12) /* UTP Error Status */
-#define RT_UFS_REG_IS_HCFES RT_BIT(16) /* Host Controller Fatal Error Status */
-#define RT_UFS_REG_IS_SBFES RT_BIT(17) /* System Bus Fatal Error Status */
-#define RT_UFS_REG_IE 0x24 /* Interrupt Enable */
-#define RT_UFS_REG_IE_UTRCE RT_BIT(0) /* UTP Transfer Request Completion Enable */
-#define RT_UFS_REG_IE_UDEPRIE RT_BIT(1) /* UIC DME_ENDPOINTRESET */
-#define RT_UFS_REG_IE_UEE RT_BIT(2) /* UIC Error Enable */
-#define RT_UFS_REG_IE_UTMSE RT_BIT(3) /* UIC Test Mode Status Enable */
-#define RT_UFS_REG_IE_UPMSE RT_BIT(4) /* UIC Power Mode Status Enable */
-#define RT_UFS_REG_IE_UHXSE RT_BIT(5) /* UIC Hibernate Exit Status Enable */
-#define RT_UFS_REG_IE_UHESE RT_BIT(6) /* UIC Hibernate Enter Status Enable */
-#define RT_UFS_REG_IE_ULLSE RT_BIT(7) /* UIC Link Lost Status Enable */
-#define RT_UFS_REG_IE_ULSSE RT_BIT(8) /* UIC Link Startup Status Enable */
-#define RT_UFS_REG_IE_UTMRCE RT_BIT(9) /* UTP Task Management Request Completion Enable */
-#define RT_UFS_REG_IE_UCCE RT_BIT(10) /* UIC COMMAND Completion Enable */
-#define RT_UFS_REG_IE_DFEE RT_BIT(11) /* Device Fatal Error Enable */
-#define RT_UFS_REG_IE_UTPEE RT_BIT(12) /* UTP Error Enable */
-#define RT_UFS_REG_IE_HCFEE RT_BIT(16) /* Host Controller Fatal Error Enable */
-#define RT_UFS_REG_IE_SBFEE RT_BIT(17) /* System Bus Fatal Error Enable */
-#define RT_UFS_REG_HCS 0x30 /* Host Controller Status */
-#define RT_UFS_REG_HCS_DP RT_BIT(0) /* Device Present */
-#define RT_UFS_REG_HCS_UTRLRDY RT_BIT(1) /* UTP Transfer Request List Ready */
-#define RT_UFS_REG_HCS_UTMRLRDY RT_BIT(2) /* UTP Task Management Request List Ready */
-#define RT_UFS_REG_HCS_UCRDY RT_BIT(3) /* UIC COMMAND Ready */
-#define RT_UFS_REG_HCS_UPMCRS(v) __BIT_FIELD(v, 10, 8) /* UIC Power Mode Change Request Status */
-#define RT_UFS_REG_HCS_UTPEC(v) __BIT_FIELD(v, 15, 12) /* UTP Error Code */
-#define RT_UFS_REG_HCS_TTAGUTPE(v) __BIT_FIELD(v, 23, 16) /* Task Tag of UTP error */
-#define RT_UFS_REG_HCS_TLUNUTPE(v) __BIT_FIELD(v, 31, 24) /* Target LUN of UTP error */
-#define RT_UFS_REG_HCE 0x34 /* Host Controller Enable */
-#define RT_UFS_REG_UECPA 0x38 /* Host UIC Error Code PHY Adapter Layer */
-#define RT_UFS_REG_UECPA_EC(v) __BIT_FIELD(v, 4, 0) /* UIC PHY Adapter Layer Error Code */
-#define RT_UFS_REG_UECPA_ERR RT_BIT(31) /* UIC PHY AdapterA Layer Error */
-#define RT_UFS_REG_UECDL 0x3c /* Host UIC Error Code Data Link Layer */
-#define RT_UFS_REG_UECDL_EC(v) __BIT_FIELD(v, 14, 0) /* UIC Data Link Layer Error Code */
-#define RT_UFS_REG_UECDL_ERR RT_BIT(31) /* UIC Data Link Layer Error */
-#define RT_UFS_REG_UECN 0x40 /* Host UIC Error Code Network Layer */
-#define RT_UFS_REG_UECN_EC(v) __BIT_FIELD(v, 2, 0) /* UIC Network Layer Error Code */
-#define RT_UFS_REG_UECN_ERR RT_BIT(31) /* UIC Network Layer Error */
-#define RT_UFS_REG_UECT 0x44 /* Host UIC Error Code Transport Layer */
-#define RT_UFS_REG_UECT_EC(v) __BIT_FIELD(v, 6, 0) /* UIC Transport Layer Error Code */
-#define RT_UFS_REG_UECT_ERR RT_BIT(31) /* UIC Transport Layer Error */
-#define RT_UFS_REG_UECDME 0x48 /* Host UIC Error Code DME */
-#define RT_UFS_REG_UECDME_EC(v) __BIT_FIELD(v, 0, 0) /* UIC DME Error Code */
-#define RT_UFS_REG_UECDME_ERR RT_BIT(31) /* UIC DME Error */
-#define RT_UFS_REG_UTRIACR 0x4c /* UTP Transfer Request Interrupt Aggregation Control Register */
-#define RT_UFS_REG_UTRIACR_IAEN RT_BIT(31) /* Interrupt Aggregation Enable/Disable */
-#define RT_UFS_REG_UTRIACR_IAPWEN RT_BIT(24) /* Interrupt aggregation parameter write enable */
-#define RT_UFS_REG_UTRIACR_IASB RT_BIT(20) /* Interrupt aggregation status bit */
-#define RT_UFS_REG_UTRIACR_CTR RT_BIT(16) /* Counter and Timer Reset */
-#define RT_UFS_REG_UTRIACR_IACTH(v) __BIT_FIELD(v, 12, 8) /* Interrupt aggregation counter threshold */
-#define RT_UFS_REG_UTRIACR_IATOVAL(v) __BIT_FIELD(v, 7, 0) /* Interrupt aggregation timeout (40us units) */
+#define RT_UFS_REG_IS 0x20 /* Interrupt Status */
+#define RT_UFS_REG_IS_UTRCS RT_BIT(0) /* UTP Transfer Request Completion Status */
+#define RT_UFS_REG_IS_UDEPRI RT_BIT(1) /* UIC DME_ENDPOINTRESET Indication */
+#define RT_UFS_REG_IS_UE RT_BIT(2) /* UIC Error */
+#define RT_UFS_REG_IS_UTMS RT_BIT(3) /* UIC Test Mode Status */
+#define RT_UFS_REG_IS_UPMS RT_BIT(4) /* UIC Power Mode Status */
+#define RT_UFS_REG_IS_UHXS RT_BIT(5) /* UIC Hibernate Exit Status */
+#define RT_UFS_REG_IS_UHES RT_BIT(6) /* UIC Hibernate Enter Status */
+#define RT_UFS_REG_IS_ULLS RT_BIT(7) /* UIC Link Lost Status */
+#define RT_UFS_REG_IS_ULSS RT_BIT(8) /* UIC Link Startup Status */
+#define RT_UFS_REG_IS_UTMRCS RT_BIT(9) /* UTP Task Management Request Completion Status */
+#define RT_UFS_REG_IS_UCCS RT_BIT(10) /* UIC Command Completion Status */
+#define RT_UFS_REG_IS_DFES RT_BIT(11) /* Device Fatal Error Status */
+#define RT_UFS_REG_IS_UTPES RT_BIT(12) /* UTP Error Status */
+#define RT_UFS_REG_IS_HCFES RT_BIT(16) /* Host Controller Fatal Error Status */
+#define RT_UFS_REG_IS_SBFES RT_BIT(17) /* System Bus Fatal Error Status */
+#define RT_UFS_REG_IE 0x24 /* Interrupt Enable */
+#define RT_UFS_REG_IE_UTRCE RT_BIT(0) /* UTP Transfer Request Completion Enable */
+#define RT_UFS_REG_IE_UDEPRIE RT_BIT(1) /* UIC DME_ENDPOINTRESET */
+#define RT_UFS_REG_IE_UEE RT_BIT(2) /* UIC Error Enable */
+#define RT_UFS_REG_IE_UTMSE RT_BIT(3) /* UIC Test Mode Status Enable */
+#define RT_UFS_REG_IE_UPMSE RT_BIT(4) /* UIC Power Mode Status Enable */
+#define RT_UFS_REG_IE_UHXSE RT_BIT(5) /* UIC Hibernate Exit Status Enable */
+#define RT_UFS_REG_IE_UHESE RT_BIT(6) /* UIC Hibernate Enter Status Enable */
+#define RT_UFS_REG_IE_ULLSE RT_BIT(7) /* UIC Link Lost Status Enable */
+#define RT_UFS_REG_IE_ULSSE RT_BIT(8) /* UIC Link Startup Status Enable */
+#define RT_UFS_REG_IE_UTMRCE RT_BIT(9) /* UTP Task Management Request Completion Enable */
+#define RT_UFS_REG_IE_UCCE RT_BIT(10) /* UIC COMMAND Completion Enable */
+#define RT_UFS_REG_IE_DFEE RT_BIT(11) /* Device Fatal Error Enable */
+#define RT_UFS_REG_IE_UTPEE RT_BIT(12) /* UTP Error Enable */
+#define RT_UFS_REG_IE_HCFEE RT_BIT(16) /* Host Controller Fatal Error Enable */
+#define RT_UFS_REG_IE_SBFEE RT_BIT(17) /* System Bus Fatal Error Enable */
+#define RT_UFS_REG_HCS 0x30 /* Host Controller Status */
+#define RT_UFS_REG_HCS_DP RT_BIT(0) /* Device Present */
+#define RT_UFS_REG_HCS_UTRLRDY RT_BIT(1) /* UTP Transfer Request List Ready */
+#define RT_UFS_REG_HCS_UTMRLRDY RT_BIT(2) /* UTP Task Management Request List Ready */
+#define RT_UFS_REG_HCS_UCRDY RT_BIT(3) /* UIC COMMAND Ready */
+#define RT_UFS_REG_HCS_UPMCRS(v) __BIT_FIELD(v, 10, 8) /* UIC Power Mode Change Request Status */
+#define RT_UFS_REG_HCS_UTPEC(v) __BIT_FIELD(v, 15, 12) /* UTP Error Code */
+#define RT_UFS_REG_HCS_TTAGUTPE(v) __BIT_FIELD(v, 23, 16) /* Task Tag of UTP error */
+#define RT_UFS_REG_HCS_TLUNUTPE(v) __BIT_FIELD(v, 31, 24) /* Target LUN of UTP error */
+#define RT_UFS_REG_HCE 0x34 /* Host Controller Enable */
+#define RT_UFS_REG_UECPA 0x38 /* Host UIC Error Code PHY Adapter Layer */
+#define RT_UFS_REG_UECPA_EC(v) __BIT_FIELD(v, 4, 0) /* UIC PHY Adapter Layer Error Code */
+#define RT_UFS_REG_UECPA_ERR RT_BIT(31) /* UIC PHY AdapterA Layer Error */
+#define RT_UFS_REG_UECDL 0x3c /* Host UIC Error Code Data Link Layer */
+#define RT_UFS_REG_UECDL_EC(v) __BIT_FIELD(v, 14, 0) /* UIC Data Link Layer Error Code */
+#define RT_UFS_REG_UECDL_ERR RT_BIT(31) /* UIC Data Link Layer Error */
+#define RT_UFS_REG_UECN 0x40 /* Host UIC Error Code Network Layer */
+#define RT_UFS_REG_UECN_EC(v) __BIT_FIELD(v, 2, 0) /* UIC Network Layer Error Code */
+#define RT_UFS_REG_UECN_ERR RT_BIT(31) /* UIC Network Layer Error */
+#define RT_UFS_REG_UECT 0x44 /* Host UIC Error Code Transport Layer */
+#define RT_UFS_REG_UECT_EC(v) __BIT_FIELD(v, 6, 0) /* UIC Transport Layer Error Code */
+#define RT_UFS_REG_UECT_ERR RT_BIT(31) /* UIC Transport Layer Error */
+#define RT_UFS_REG_UECDME 0x48 /* Host UIC Error Code DME */
+#define RT_UFS_REG_UECDME_EC(v) __BIT_FIELD(v, 0, 0) /* UIC DME Error Code */
+#define RT_UFS_REG_UECDME_ERR RT_BIT(31) /* UIC DME Error */
+#define RT_UFS_REG_UTRIACR 0x4c /* UTP Transfer Request Interrupt Aggregation Control Register */
+#define RT_UFS_REG_UTRIACR_IAEN RT_BIT(31) /* Interrupt Aggregation Enable/Disable */
+#define RT_UFS_REG_UTRIACR_IAPWEN RT_BIT(24) /* Interrupt aggregation parameter write enable */
+#define RT_UFS_REG_UTRIACR_IASB RT_BIT(20) /* Interrupt aggregation status bit */
+#define RT_UFS_REG_UTRIACR_CTR RT_BIT(16) /* Counter and Timer Reset */
+#define RT_UFS_REG_UTRIACR_IACTH(v) __BIT_FIELD(v, 12, 8) /* Interrupt aggregation counter threshold */
+#define RT_UFS_REG_UTRIACR_IATOVAL(v) __BIT_FIELD(v, 7, 0) /* Interrupt aggregation timeout (40us units) */
/* UTRIACR compose */
-#define RT_UFS_UTRIACR_TIMEOUT_MASK RT_GENMASK(7, 0)
-#define RT_UFS_UTRIACR_COUNTER_THLD_MASK RT_GENMASK(12, 8)
-#define RT_UFS_UTRIACR_CTR RT_BIT(16)
-#define RT_UFS_UTRIACR_IASB RT_BIT(20)
-#define RT_UFS_UTRIACR_IAPWEN RT_BIT(24)
-#define RT_UFS_UTRIACR_IAEN RT_BIT(31)
-#define RT_UFS_UTRIACR_COUNTER_THLD(c) ((((rt_uint32_t)(c)) & 0x1fu) << 8)
-#define RT_UFS_UTRIACR_TIMEOUT(t) (((rt_uint32_t)(t)) & 0xffu)
-#define RT_UFS_UTRIACR_ENABLE_PARAMS(cnt, to) (RT_UFS_UTRIACR_IAEN | RT_UFS_UTRIACR_IAPWEN | \
- RT_UFS_UTRIACR_COUNTER_THLD(cnt) | RT_UFS_UTRIACR_TIMEOUT(to))
-#define RT_UFS_UTRIACR_RESET (RT_UFS_UTRIACR_IAEN | RT_UFS_UTRIACR_CTR)
+#define RT_UFS_UTRIACR_TIMEOUT_MASK RT_GENMASK(7, 0)
+#define RT_UFS_UTRIACR_COUNTER_THLD_MASK RT_GENMASK(12, 8)
+#define RT_UFS_UTRIACR_CTR RT_BIT(16)
+#define RT_UFS_UTRIACR_IASB RT_BIT(20)
+#define RT_UFS_UTRIACR_IAPWEN RT_BIT(24)
+#define RT_UFS_UTRIACR_IAEN RT_BIT(31)
+#define RT_UFS_UTRIACR_COUNTER_THLD(c) ((((rt_uint32_t)(c)) & 0x1fu) << 8)
+#define RT_UFS_UTRIACR_TIMEOUT(t) (((rt_uint32_t)(t)) & 0xffu)
+#define RT_UFS_UTRIACR_ENABLE_PARAMS(cnt, to) (RT_UFS_UTRIACR_IAEN | RT_UFS_UTRIACR_IAPWEN | \
+ RT_UFS_UTRIACR_COUNTER_THLD(cnt) | RT_UFS_UTRIACR_TIMEOUT(to))
+#define RT_UFS_UTRIACR_RESET (RT_UFS_UTRIACR_IAEN | RT_UFS_UTRIACR_CTR)
/* UTP Transfer */
-#define RT_UFS_REG_UTRLBA 0x50 /* UTP Transfer Request List Base Address */
-#define RT_UFS_REG_UTRLBA_MASK(v) __BIT_FIELD(v, 31, 10)
-#define RT_UFS_REG_UTRLBAU 0x54 /* UTP Transfer Request List Base Address Upper 32-Bits */
-#define RT_UFS_REG_UTRLBAU_MASK(v) __BIT_FIELD(v, 31, 0)
-#define RT_UFS_REG_UTRLDBR 0x58 /* UTP Transfer Request List Door Bell Register */
-#define RT_UFS_REG_UTRLCLR 0x5c /* UTP Transfer Request List CLear Register */
-#define RT_UFS_REG_UTRLRSR 0x60 /* UTP Transfer Request Run-Stop Register */
+#define RT_UFS_REG_UTRLBA 0x50 /* UTP Transfer Request List Base Address */
+#define RT_UFS_REG_UTRLBA_MASK(v) __BIT_FIELD(v, 31, 10)
+#define RT_UFS_REG_UTRLBAU 0x54 /* UTP Transfer Request List Base Address Upper 32-Bits */
+#define RT_UFS_REG_UTRLBAU_MASK(v) __BIT_FIELD(v, 31, 0)
+#define RT_UFS_REG_UTRLDBR 0x58 /* UTP Transfer Request List Door Bell Register */
+#define RT_UFS_REG_UTRLCLR 0x5c /* UTP Transfer Request List CLear Register */
+#define RT_UFS_REG_UTRLRSR 0x60 /* UTP Transfer Request Run-Stop Register */
/* UTP Task Managemeng */
-#define RT_UFS_REG_UTMRLBA 0x70 /* UTP Task Management Request List Base Address */
-#define RT_UFS_REG_UTMRLBA_MASK(v) __BIT_FIELD(v, 31, 10)
-#define RT_UFS_REG_UTMRLBAU 0x74 /* UTP Task Management Request List Base Address Upper 32-Bits */
-#define RT_UFS_REG_UTMRLBAU_MASK(v) __BIT_FIELD(v, 31, 0)
-#define RT_UFS_REG_UTMRLDBR 0x78 /* UTP Task Management Request List Door Bell Register */
-#define RT_UFS_REG_UTMRLCLR 0x7c /* UTP Task Management Request List CLear Register */
-#define RT_UFS_REG_UTMRLRSR 0x80 /* UTP Task Management Run-Stop Register */
+#define RT_UFS_REG_UTMRLBA 0x70 /* UTP Task Management Request List Base Address */
+#define RT_UFS_REG_UTMRLBA_MASK(v) __BIT_FIELD(v, 31, 10)
+#define RT_UFS_REG_UTMRLBAU 0x74 /* UTP Task Management Request List Base Address Upper 32-Bits */
+#define RT_UFS_REG_UTMRLBAU_MASK(v) __BIT_FIELD(v, 31, 0)
+#define RT_UFS_REG_UTMRLDBR 0x78 /* UTP Task Management Request List Door Bell Register */
+#define RT_UFS_REG_UTMRLCLR 0x7c /* UTP Task Management Request List CLear Register */
+#define RT_UFS_REG_UTMRLRSR 0x80 /* UTP Task Management Run-Stop Register */
/* UIC Command */
-#define RT_UFS_REG_UICCMD 0x90 /* UIC Command Register */
-#define RT_UFS_REG_UICCMD_CMDOP(v) __BIT_FIELD(v, 7, 0) /* Command Opcode */
-#define RT_UFS_REG_UCMDARG1 0x94 /* UIC Command Argument 1 */
-#define RT_UFS_REG_UCMDARG2 0x98 /* UIC Command Argument 2 */
-#define RT_UFS_REG_UCMDARG3 0x9c /* UIC Command Argument 3 */
+#define RT_UFS_REG_UICCMD 0x90 /* UIC Command Register */
+#define RT_UFS_REG_UICCMD_CMDOP(v) __BIT_FIELD(v, 7, 0) /* Command Opcode */
+#define RT_UFS_REG_UCMDARG1 0x94 /* UIC Command Argument 1 */
+#define RT_UFS_REG_UCMDARG2 0x98 /* UIC Command Argument 2 */
+#define RT_UFS_REG_UCMDARG3 0x9c /* UIC Command Argument 3 */
/* UMA */
-#define RT_UFS_REG_UMA_EXT 0xb0 /* Reserved for Unified Memory Extension */
+#define RT_UFS_REG_UMA_EXT 0xb0 /* Reserved for Unified Memory Extension */
/* Vendor Specific */
-#define RT_UFS_REG_VS 0xc0 /* Vendor Specific Registers */
+#define RT_UFS_REG_VS 0xc0 /* Vendor Specific Registers */
/* UTP Error Code */
enum
{
- RT_UFS_UTPEC_ERR_INV_TYPE = 1,
+ RT_UFS_UTPEC_ERR_INV_TYPE = 1,
};
/* UIC Power Mode Change Request Status */
enum
{
- RT_UFS_UPMCRS_PWR_OK = 0x0,
- RT_UFS_UPMCRS_PWR_LOCAL = 0x1,
- RT_UFS_UPMCRS_PWR_REMOTE = 0x2,
- RT_UFS_UPMCRS_PWR_BUSY = 0x3,
- RT_UFS_UPMCRS_PWR_ERROR_CAP = 0x4,
- RT_UFS_UPMCRS_PWR_FATAL_ERROR = 0x5,
+ RT_UFS_UPMCRS_PWR_OK = 0x0,
+ RT_UFS_UPMCRS_PWR_LOCAL = 0x1,
+ RT_UFS_UPMCRS_PWR_REMOTE = 0x2,
+ RT_UFS_UPMCRS_PWR_BUSY = 0x3,
+ RT_UFS_UPMCRS_PWR_ERROR_CAP = 0x4,
+ RT_UFS_UPMCRS_PWR_FATAL_ERROR = 0x5,
};
/* UIC PHY Adapter Layer Error Code */
enum
{
- RT_UFS_UECPA_EC_LANE0 = RT_BIT(0),
- RT_UFS_UECPA_EC_LANE1 = RT_BIT(1),
- RT_UFS_UECPA_EC_LANE2 = RT_BIT(2),
- RT_UFS_UECPA_EC_LANE3 = RT_BIT(3),
- RT_UFS_UECPA_EC_GENERIC = RT_BIT(4),
+ RT_UFS_UECPA_EC_LANE0 = RT_BIT(0),
+ RT_UFS_UECPA_EC_LANE1 = RT_BIT(1),
+ RT_UFS_UECPA_EC_LANE2 = RT_BIT(2),
+ RT_UFS_UECPA_EC_LANE3 = RT_BIT(3),
+ RT_UFS_UECPA_EC_GENERIC = RT_BIT(4),
};
/* UIC Data Link Layer Error Code */
enum
{
- RT_UFS_UECDL_EC_NAC_RECEIVED = RT_BIT(0),
- RT_UFS_UECDL_EC_TCx_REPLAY_TIMER_EXPIRED = RT_BIT(1),
- RT_UFS_UECDL_EC_AFCx_REQUEST_TIMER_EXPIRED = RT_BIT(2),
- RT_UFS_UECDL_EC_FCx_PROTECTION_TIMER_EXPIRED = RT_BIT(3),
- RT_UFS_UECDL_EC_CRC_ERROR = RT_BIT(4),
- RT_UFS_UECDL_EC_RX_BUFFER_OVERFLOW = RT_BIT(5),
- RT_UFS_UECDL_EC_MAX_FRAME_LENGTH_EXCEEDED = RT_BIT(6),
- RT_UFS_UECDL_EC_WRONG_SEQUENCE_NUMBER = RT_BIT(7),
- RT_UFS_UECDL_EC_AFC_FRAME_SYNTAX_ERROR = RT_BIT(8),
- RT_UFS_UECDL_EC_NAC_FRAME_SYNTAX_ERROR = RT_BIT(9),
- RT_UFS_UECDL_EC_EOF_SYNTAX_ERROR = RT_BIT(10),
- RT_UFS_UECDL_EC_FRAME_SYNTAX_ERROR = RT_BIT(11),
- RT_UFS_UECDL_EC_BAD_CTRL_SYMBOL_TYPE = RT_BIT(12),
- RT_UFS_UECDL_EC_PA_INIT_ERROR = RT_BIT(13),
- RT_UFS_UECDL_EC_PA_ERROR_IND_RECEIVED = RT_BIT(14),
+ RT_UFS_UECDL_EC_NAC_RECEIVED = RT_BIT(0),
+ RT_UFS_UECDL_EC_TCx_REPLAY_TIMER_EXPIRED = RT_BIT(1),
+ RT_UFS_UECDL_EC_AFCx_REQUEST_TIMER_EXPIRED = RT_BIT(2),
+ RT_UFS_UECDL_EC_FCx_PROTECTION_TIMER_EXPIRED = RT_BIT(3),
+ RT_UFS_UECDL_EC_CRC_ERROR = RT_BIT(4),
+ RT_UFS_UECDL_EC_RX_BUFFER_OVERFLOW = RT_BIT(5),
+ RT_UFS_UECDL_EC_MAX_FRAME_LENGTH_EXCEEDED = RT_BIT(6),
+ RT_UFS_UECDL_EC_WRONG_SEQUENCE_NUMBER = RT_BIT(7),
+ RT_UFS_UECDL_EC_AFC_FRAME_SYNTAX_ERROR = RT_BIT(8),
+ RT_UFS_UECDL_EC_NAC_FRAME_SYNTAX_ERROR = RT_BIT(9),
+ RT_UFS_UECDL_EC_EOF_SYNTAX_ERROR = RT_BIT(10),
+ RT_UFS_UECDL_EC_FRAME_SYNTAX_ERROR = RT_BIT(11),
+ RT_UFS_UECDL_EC_BAD_CTRL_SYMBOL_TYPE = RT_BIT(12),
+ RT_UFS_UECDL_EC_PA_INIT_ERROR = RT_BIT(13),
+ RT_UFS_UECDL_EC_PA_ERROR_IND_RECEIVED = RT_BIT(14),
};
/* UIC Network Layer Error Code */
enum
{
- RT_UFS_UECN_EC_UNSUPPORTED_HEADER_TYPE = RT_BIT(0),
- RT_UFS_UECN_EC_BAD_DEVICEID_ENC = RT_BIT(1),
- RT_UFS_UECN_EC_LHDR_TRAP_PACKET_DROPPING = RT_BIT(2),
+ RT_UFS_UECN_EC_UNSUPPORTED_HEADER_TYPE = RT_BIT(0),
+ RT_UFS_UECN_EC_BAD_DEVICEID_ENC = RT_BIT(1),
+ RT_UFS_UECN_EC_LHDR_TRAP_PACKET_DROPPING = RT_BIT(2),
};
/* UIC Transport Layer Error Code */
enum
{
- RT_UFS_UECT_EC_UNSUPPORTED_HEADER_TYPE = RT_BIT(0),
- RT_UFS_UECT_EC_UNKNOWN_CPORTID = RT_BIT(1),
- RT_UFS_UECT_EC_NO_CONNECTION_RX = RT_BIT(2),
- RT_UFS_UECT_EC_CONTROLLED_SEGMENT_DROPPING = RT_BIT(3),
- RT_UFS_UECT_EC_BAD_TC = RT_BIT(4),
- RT_UFS_UECT_EC_E2E_CREDIT_OVERFLOW = RT_BIT(5),
- RT_UFS_UECT_EC_SAFETY_VALVE_DROPPING = RT_BIT(6),
+ RT_UFS_UECT_EC_UNSUPPORTED_HEADER_TYPE = RT_BIT(0),
+ RT_UFS_UECT_EC_UNKNOWN_CPORTID = RT_BIT(1),
+ RT_UFS_UECT_EC_NO_CONNECTION_RX = RT_BIT(2),
+ RT_UFS_UECT_EC_CONTROLLED_SEGMENT_DROPPING = RT_BIT(3),
+ RT_UFS_UECT_EC_BAD_TC = RT_BIT(4),
+ RT_UFS_UECT_EC_E2E_CREDIT_OVERFLOW = RT_BIT(5),
+ RT_UFS_UECT_EC_SAFETY_VALVE_DROPPING = RT_BIT(6),
};
/* UIC DME Error Code */
enum
{
- RT_UFS_UECDME_EC_GENERIC = RT_BIT(0),
+ RT_UFS_UECDME_EC_GENERIC = RT_BIT(0),
};
/* UIC Command Opcode */
enum
{
/* Configuration */
- RT_UFS_CMDOP_DME_GET = 0x1,
- RT_UFS_CMDOP_DME_SET = 0x2,
- RT_UFS_CMDOP_DME_PEER_GET = 0x3,
- RT_UFS_CMDOP_DME_PEER_SET = 0x4,
+ RT_UFS_CMDOP_DME_GET = 0x1,
+ RT_UFS_CMDOP_DME_SET = 0x2,
+ RT_UFS_CMDOP_DME_PEER_GET = 0x3,
+ RT_UFS_CMDOP_DME_PEER_SET = 0x4,
/* Control */
- RT_UFS_CMDOP_DME_POWERON = 0x10,
- RT_UFS_CMDOP_DME_POWEROFF = 0x11,
- RT_UFS_CMDOP_DME_ENABLE = 0x12,
- RT_UFS_CMDOP_DME_RESET = 0x14,
- RT_UFS_CMDOP_DME_ENDPOINTRESET = 0x15,
- RT_UFS_CMDOP_DME_LINKSTARTUP = 0x16,
- RT_UFS_CMDOP_DME_HIBERNATE_ENTER = 0x17,
- RT_UFS_CMDOP_DME_HIBERNATE_EXIT = 0x18,
- RT_UFS_CMDOP_DME_TEST_MODE = 0x1a,
+ RT_UFS_CMDOP_DME_POWERON = 0x10,
+ RT_UFS_CMDOP_DME_POWEROFF = 0x11,
+ RT_UFS_CMDOP_DME_ENABLE = 0x12,
+ RT_UFS_CMDOP_DME_RESET = 0x14,
+ RT_UFS_CMDOP_DME_ENDPOINTRESET = 0x15,
+ RT_UFS_CMDOP_DME_LINKSTARTUP = 0x16,
+ RT_UFS_CMDOP_DME_HIBERNATE_ENTER = 0x17,
+ RT_UFS_CMDOP_DME_HIBERNATE_EXIT = 0x18,
+ RT_UFS_CMDOP_DME_TEST_MODE = 0x1a,
};
/* UIC Config result code / Generic error code */
enum
{
- RT_UFS_CMDRES_SUCCESS = 0x0,
- RT_UFS_CMDRES_INVALID_MIB_ATTRIBUTE = 0x1,
- RT_UFS_CMDRES_INVALID_MIB_ATTRIBUTE_VALUE = 0x2,
- RT_UFS_CMDRES_READ_ONLY_MIB_ATTRIBUTE = 0x3,
- RT_UFS_CMDRES_WRITE_ONLY_MIB_ATTRIBUTE = 0x4,
- RT_UFS_CMDRES_BAD_INDEX = 0x5,
- RT_UFS_CMDRES_LOCKED_MIB_ATTRIBUTE = 0x6,
- RT_UFS_CMDRES_BAD_TEST_FEATURE_INDEX = 0x7,
- RT_UFS_CMDRES_PEER_COMMUNICATION_FAILURE = 0x8,
- RT_UFS_CMDRES_BUSY = 0x9,
- RT_UFS_CMDRES_DME_FAILURE = 0xa,
- RT_UFS_CMDRES_MASK = 0xff,
+ RT_UFS_CMDRES_SUCCESS = 0x0,
+ RT_UFS_CMDRES_INVALID_MIB_ATTRIBUTE = 0x1,
+ RT_UFS_CMDRES_INVALID_MIB_ATTRIBUTE_VALUE = 0x2,
+ RT_UFS_CMDRES_READ_ONLY_MIB_ATTRIBUTE = 0x3,
+ RT_UFS_CMDRES_WRITE_ONLY_MIB_ATTRIBUTE = 0x4,
+ RT_UFS_CMDRES_BAD_INDEX = 0x5,
+ RT_UFS_CMDRES_LOCKED_MIB_ATTRIBUTE = 0x6,
+ RT_UFS_CMDRES_BAD_TEST_FEATURE_INDEX = 0x7,
+ RT_UFS_CMDRES_PEER_COMMUNICATION_FAILURE = 0x8,
+ RT_UFS_CMDRES_BUSY = 0x9,
+ RT_UFS_CMDRES_DME_FAILURE = 0xa,
+ RT_UFS_CMDRES_MASK = 0xff,
};
/*
* UIC DME attribute encoding (JEDEC UFS / UniPro PA)
*/
-#define RT_UFS_UIC_ARG_MIB_SEL(attr, sel) ((((rt_uint32_t)(attr) & 0xffffU) << 16) | ((rt_uint32_t)(sel) & 0xffffU))
-#define RT_UFS_UIC_ARG_MIB(attr) RT_UFS_UIC_ARG_MIB_SEL(attr, 0)
+#define RT_UFS_UIC_ARG_MIB_SEL(attr, sel) ((((rt_uint32_t)(attr) & 0xffffU) << 16) | ((rt_uint32_t)(sel) & 0xffffU))
+#define RT_UFS_UIC_ARG_MIB(attr) RT_UFS_UIC_ARG_MIB_SEL(attr, 0)
/* PHY Adapter — subset used for power / link configuration */
-#define RT_UFS_PA_RXGEAR 0x1583
-#define RT_UFS_PA_TXGEAR 0x1568
-#define RT_UFS_PA_ACTIVERXDATALANES 0x1580
-#define RT_UFS_PA_ACTIVETXDATALANES 0x1560
-#define RT_UFS_PA_RXTERMINATION 0x1584
-#define RT_UFS_PA_TXTERMINATION 0x1569
-#define RT_UFS_PA_HSSERIES 0x156a
-#define RT_UFS_PA_PWRMODE 0x1571
-#define RT_UFS_PA_PWRMODEUSERDATA0 0x15b0
-#define RT_UFS_PA_PWRMODEUSERDATA1 0x15b1
-#define RT_UFS_PA_PWRMODEUSERDATA2 0x15b2
-#define RT_UFS_PA_PWRMODEUSERDATA3 0x15b3
-#define RT_UFS_PA_PWRMODEUSERDATA4 0x15b4
-#define RT_UFS_PA_PWRMODEUSERDATA5 0x15b5
-#define RT_UFS_DME_LOCAL_FC0_PROT_TO 0xd041
-#define RT_UFS_DME_LOCAL_TC0_REPLAY_TO 0xd042
-#define RT_UFS_DME_LOCAL_AFC0_REQ_TO 0xd043
+#define RT_UFS_PA_RXGEAR 0x1583
+#define RT_UFS_PA_TXGEAR 0x1568
+#define RT_UFS_PA_ACTIVERXDATALANES 0x1580
+#define RT_UFS_PA_ACTIVETXDATALANES 0x1560
+#define RT_UFS_PA_RXTERMINATION 0x1584
+#define RT_UFS_PA_TXTERMINATION 0x1569
+#define RT_UFS_PA_HSSERIES 0x156a
+#define RT_UFS_PA_PWRMODE 0x1571
+#define RT_UFS_PA_PWRMODEUSERDATA0 0x15b0
+#define RT_UFS_PA_PWRMODEUSERDATA1 0x15b1
+#define RT_UFS_PA_PWRMODEUSERDATA2 0x15b2
+#define RT_UFS_PA_PWRMODEUSERDATA3 0x15b3
+#define RT_UFS_PA_PWRMODEUSERDATA4 0x15b4
+#define RT_UFS_PA_PWRMODEUSERDATA5 0x15b5
+#define RT_UFS_DME_LOCAL_FC0_PROT_TO 0xd041
+#define RT_UFS_DME_LOCAL_TC0_REPLAY_TO 0xd042
+#define RT_UFS_DME_LOCAL_AFC0_REQ_TO 0xd043
-#define RT_UFS_DL_FC0_PROT_TO_DEFAULT 8191U
-#define RT_UFS_DL_TC0_REPLAY_TO_DEFAULT 65535U
-#define RT_UFS_DL_AFC0_REQ_TO_DEFAULT 32767U
-#define RT_UFS_DL_FC1_PROT_TO_DEFAULT 8191U
-#define RT_UFS_DL_TC1_REPLAY_TO_DEFAULT 65535U
-#define RT_UFS_DL_AFC1_REQ_TO_DEFAULT 32767U
+#define RT_UFS_DL_FC0_PROT_TO_DEFAULT 8191U
+#define RT_UFS_DL_TC0_REPLAY_TO_DEFAULT 65535U
+#define RT_UFS_DL_AFC0_REQ_TO_DEFAULT 32767U
+#define RT_UFS_DL_FC1_PROT_TO_DEFAULT 8191U
+#define RT_UFS_DL_TC1_REPLAY_TO_DEFAULT 65535U
+#define RT_UFS_DL_AFC1_REQ_TO_DEFAULT 32767U
enum rt_ufs_pa_pwr_mode
{
- RT_UFS_PA_FAST_MODE = 1,
- RT_UFS_PA_SLOW_MODE = 2,
- RT_UFS_PA_FASTAUTO_MODE = 4,
- RT_UFS_PA_SLOWAUTO_MODE = 5,
- RT_UFS_PA_UNCHANGED_MODE = 7,
+ RT_UFS_PA_FAST_MODE = 1,
+ RT_UFS_PA_SLOW_MODE = 2,
+ RT_UFS_PA_FASTAUTO_MODE = 4,
+ RT_UFS_PA_SLOWAUTO_MODE = 5,
+ RT_UFS_PA_UNCHANGED_MODE = 7,
};
enum rt_ufs_pa_hs_rate
{
- RT_UFS_PA_HS_MODE_A = 1,
- RT_UFS_PA_HS_MODE_B = 2,
+ RT_UFS_PA_HS_MODE_A = 1,
+ RT_UFS_PA_HS_MODE_B = 2,
};
/* Auto-Hibernate Idle Timer (AHIT) — REG 0x18 */
-#define RT_UFS_AHIT_TIMER_MASK RT_GENMASK(9, 0)
-#define RT_UFS_AHIT_SCALE_MASK RT_GENMASK(12, 10)
+#define RT_UFS_AHIT_TIMER_MASK RT_GENMASK(9, 0)
+#define RT_UFS_AHIT_SCALE_MASK RT_GENMASK(12, 10)
rt_inline rt_uint32_t rt_ufs_ahit_encode(rt_uint16_t timer, rt_uint8_t scale)
{
@@ -312,68 +312,67 @@ rt_inline rt_uint32_t rt_ufs_ahit_encode(rt_uint16_t timer, rt_uint8_t scale)
}
/* 150 * 10^3 us idle before auto-Hibernate8 */
-#define RT_UFS_AHIT_DEFAULT rt_ufs_ahit_encode(150, 3)
+#define RT_UFS_AHIT_DEFAULT rt_ufs_ahit_encode(150, 3)
/*
* UTP / UPIU (refer to JEDEC UFS & UFSHCI)
*/
-#define RT_UFS_CDB_SIZE 16
-#define RT_UFS_ALIGNED_UPIU_SIZE 512
-#define RT_UFS_SENSE_SIZE 18
+#define RT_UFS_CDB_SIZE 16
+#define RT_UFS_ALIGNED_UPIU_SIZE 512
+#define RT_UFS_SENSE_SIZE 18
/* UTP Transfer Request Command Type */
-#define RT_UTP_CMD_TYPE_SCSI 0x0
-#define RT_UTP_CMD_TYPE_UFS_STORAGE 0x1
-#define RT_UTP_CMD_TYPE_DEV_MANAGE 0x2
+#define RT_UTP_CMD_TYPE_SCSI 0x0
+#define RT_UTP_CMD_TYPE_UFS_STORAGE 0x1
+#define RT_UTP_CMD_TYPE_DEV_MANAGE 0x2
/* UTP Data Direction */
-#define RT_UTP_NO_DATA_TRANSFER 0
-#define RT_UTP_HOST_TO_DEVICE 1
-#define RT_UTP_DEVICE_TO_HOST 2
+#define RT_UTP_NO_DATA_TRANSFER 0
+#define RT_UTP_HOST_TO_DEVICE 1
+#define RT_UTP_DEVICE_TO_HOST 2
/* Overall Command Status (OCS) in UTRD */
enum rt_ufs_ocs
{
- RT_UFS_OCS_SUCCESS = 0x0,
- RT_UFS_OCS_INVALID_CMD_TABLE_ATTR = 0x1,
- RT_UFS_OCS_INVALID_PRDT_ATTR = 0x2,
- RT_UFS_OCS_MISMATCH_DATA_BUF_SIZE = 0x3,
- RT_UFS_OCS_MISMATCH_RESP_UPIU_SIZE = 0x4,
- RT_UFS_OCS_PEER_COMM_FAILURE = 0x5,
- RT_UFS_OCS_ABORTED = 0x6,
- RT_UFS_OCS_FATAL_ERROR = 0x7,
- RT_UFS_OCS_DEVICE_FATAL_ERROR = 0x8,
- RT_UFS_OCS_INVALID_COMMAND_STATUS = 0xf,
+ RT_UFS_OCS_SUCCESS = 0x0,
+ RT_UFS_OCS_INVALID_CMD_TABLE_ATTR = 0x1,
+ RT_UFS_OCS_INVALID_PRDT_ATTR = 0x2,
+ RT_UFS_OCS_MISMATCH_DATA_BUF_SIZE = 0x3,
+ RT_UFS_OCS_MISMATCH_RESP_UPIU_SIZE = 0x4,
+ RT_UFS_OCS_PEER_COMM_FAILURE = 0x5,
+ RT_UFS_OCS_ABORTED = 0x6,
+ RT_UFS_OCS_FATAL_ERROR = 0x7,
+ RT_UFS_OCS_DEVICE_FATAL_ERROR = 0x8,
+ RT_UFS_OCS_INVALID_COMMAND_STATUS = 0xf,
};
/* UPIU Transaction Codes (Initiator to Target) */
-#define RT_UPIU_TRANSACTION_NOP_OUT 0x00
-#define RT_UPIU_TRANSACTION_COMMAND 0x01
-#define RT_UPIU_TRANSACTION_DATA_OUT 0x02
-#define RT_UPIU_TRANSACTION_TASK_REQ 0x04
-#define RT_UPIU_TRANSACTION_QUERY_REQ 0x16
+#define RT_UPIU_TRANSACTION_NOP_OUT 0x00
+#define RT_UPIU_TRANSACTION_COMMAND 0x01
+#define RT_UPIU_TRANSACTION_DATA_OUT 0x02
+#define RT_UPIU_TRANSACTION_TASK_REQ 0x04
+#define RT_UPIU_TRANSACTION_QUERY_REQ 0x16
/* UPIU Transaction Codes (Target to Initiator) */
-#define RT_UPIU_TRANSACTION_NOP_IN 0x20
-#define RT_UPIU_TRANSACTION_RESPONSE 0x21
-#define RT_UPIU_TRANSACTION_DATA_IN 0x22
-#define RT_UPIU_TRANSACTION_TASK_RSP 0x24
-#define RT_UPIU_TRANSACTION_QUERY_RSP 0x36
+#define RT_UPIU_TRANSACTION_NOP_IN 0x20
+#define RT_UPIU_TRANSACTION_RESPONSE 0x21
+#define RT_UPIU_TRANSACTION_DATA_IN 0x22
+#define RT_UPIU_TRANSACTION_TASK_RSP 0x24
+#define RT_UPIU_TRANSACTION_QUERY_RSP 0x36
/* UPIU Command Set Type */
-#define RT_UPIU_COMMAND_SET_TYPE_SCSI 0x0
+#define RT_UPIU_COMMAND_SET_TYPE_SCSI 0x0
/* UPIU Command flags */
-#define RT_UPIU_CMD_FLAGS_NONE 0x00
-#define RT_UPIU_CMD_FLAGS_WRITE 0x20
-#define RT_UPIU_CMD_FLAGS_READ 0x40
+#define RT_UPIU_CMD_FLAGS_NONE 0x00
+#define RT_UPIU_CMD_FLAGS_WRITE 0x20
+#define RT_UPIU_CMD_FLAGS_READ 0x40
/* PRDT: max single entry size 256KB, granularity 4 bytes */
-#define RT_UFS_PRDT_BYTE_COUNT_MAX (256 * 1024)
+#define RT_UFS_PRDT_BYTE_COUNT_MAX (256 * 1024)
/* UPIU header - 12 bytes, big-endian */
-rt_packed(struct rt_utp_upiu_header
-{
+rt_packed(struct rt_utp_upiu_header {
rt_uint8_t transaction_code;
rt_uint8_t flags;
rt_uint8_t lun;
@@ -384,49 +383,43 @@ rt_packed(struct rt_utp_upiu_header
rt_uint8_t status;
rt_uint8_t ehs_length;
rt_uint8_t device_information;
- rt_be16_t data_segment_length;
+ rt_be16_t data_segment_length;
});
/* Command UPIU - SCSI CDB */
-rt_packed(struct rt_utp_upiu_cmd
-{
- rt_be32_t exp_data_transfer_len;
+rt_packed(struct rt_utp_upiu_cmd {
+ rt_be32_t exp_data_transfer_len;
rt_uint8_t cdb[RT_UFS_CDB_SIZE];
});
/* Request UPIU - command type */
-rt_packed(struct rt_utp_upiu_req
-{
+rt_packed(struct rt_utp_upiu_req {
struct rt_utp_upiu_header header;
- struct rt_utp_upiu_cmd sc;
+ struct rt_utp_upiu_cmd sc;
});
/* Response UPIU - SCSI response (cmd_rsp) */
-rt_packed(struct rt_utp_cmd_rsp
-{
- rt_be32_t residual_transfer_count;
- rt_be32_t reserved[4];
- rt_be16_t sense_data_len;
+rt_packed(struct rt_utp_cmd_rsp {
+ rt_be32_t residual_transfer_count;
+ rt_be32_t reserved[4];
+ rt_be16_t sense_data_len;
rt_uint8_t sense_data[RT_UFS_SENSE_SIZE];
});
-rt_packed(struct rt_utp_upiu_rsp
-{
+rt_packed(struct rt_utp_upiu_rsp {
struct rt_utp_upiu_header header;
- struct rt_utp_cmd_rsp sr;
+ struct rt_utp_cmd_rsp sr;
});
/* Physical Region Descriptor Table entry (LE, used by controller) */
-rt_packed(struct rt_ufs_sg_entry
-{
+rt_packed(struct rt_ufs_sg_entry {
rt_uint64_t addr; /* LE in memory for UFSHCI */
rt_uint32_t reserved;
rt_uint32_t size; /* LE */
});
/* Request Descriptor Header - common to UTRD/UTMRD (4DW) */
-rt_packed(struct rt_ufs_request_desc_header
-{
+rt_packed(struct rt_ufs_request_desc_header {
rt_uint32_t dword_0;
rt_uint32_t dword_1;
rt_uint32_t dword_2;
@@ -438,8 +431,7 @@ rt_packed(struct rt_ufs_request_desc_header
#define RT_UFS_UTP_REQ_DESC_INT_CMD 0x01000000
/* UTP Transfer Request Descriptor (UTRD) - 32 bytes, host byte order for HC (LE in spec) */
-rt_packed(struct rt_utp_transfer_req_desc
-{
+rt_packed(struct rt_utp_transfer_req_desc {
struct rt_ufs_request_desc_header header;
/* DW 4-5: UCD base address low/high dwords */
rt_uint32_t command_desc_base_addr_lo; /* 128-byte aligned, HC reads as LE */
@@ -453,8 +445,8 @@ rt_packed(struct rt_utp_transfer_req_desc
/* UTP Transfer Command Descriptor (UCD) - command_upiu + response_upiu + prd_table */
struct rt_utp_transfer_cmd_desc
{
- rt_uint8_t command_upiu[RT_UFS_ALIGNED_UPIU_SIZE];
- rt_uint8_t response_upiu[RT_UFS_ALIGNED_UPIU_SIZE];
+ rt_uint8_t command_upiu[RT_UFS_ALIGNED_UPIU_SIZE];
+ rt_uint8_t response_upiu[RT_UFS_ALIGNED_UPIU_SIZE];
struct rt_ufs_sg_entry prd_table[];
};
@@ -464,8 +456,8 @@ struct rt_utp_transfer_cmd_desc
* Partition probing may read multiple blocks with buffers not page-aligned,
* so we keep a generous entry count to safely split by page boundaries.
*/
-#define RT_UFS_PRDT_ENTRIES_PER_SLOT 32
-#define RT_UFS_UCD_SIZE (RT_UFS_ALIGNED_UPIU_SIZE * 2 + sizeof(struct rt_ufs_sg_entry) * RT_UFS_PRDT_ENTRIES_PER_SLOT)
+#define RT_UFS_PRDT_ENTRIES_PER_SLOT 32
+#define RT_UFS_UCD_SIZE (RT_UFS_ALIGNED_UPIU_SIZE * 2 + sizeof(struct rt_ufs_sg_entry) * RT_UFS_PRDT_ENTRIES_PER_SLOT)
struct rt_ufs_ops;
struct rt_ufs_host;
@@ -493,7 +485,7 @@ struct rt_ufs_host
struct rt_scsi_host parent;
void *regs;
- int irq;
+ int irq;
rt_uint32_t cap;
rt_uint32_t nutrs; /* Number of UTP transfer request slots, 1..32 */
@@ -502,34 +494,34 @@ struct rt_ufs_host
/* UTRL (UTRD list) base (must be 1KB aligned); we use slot0 only */
struct rt_utp_transfer_req_desc *utrd; /* Points to utrl_base[0] */
- void *utrl_base; /* Full UTRL base */
- rt_size_t utrl_size; /* Bytes */
- rt_ubase_t utrl_handle;
+ void *utrl_base; /* Full UTRL base */
+ rt_size_t utrl_size; /* Bytes */
+ rt_ubase_t utrl_handle;
/* UTMRL (UTMRD list) base (must be 1KB aligned); placeholder for now */
- void *utmrl_base;
- rt_size_t utmrl_size;
+ void *utmrl_base;
+ rt_size_t utmrl_size;
rt_ubase_t utmrl_handle;
rt_uint8_t utmrl_coherent;
rt_uint8_t *ucd_base; /* One UCD: command_upiu + response_upiu + prd_table */
- rt_size_t ucd_size; /* RT_UFS_UCD_SIZE or platform value */
- rt_ubase_t ucd_handle;
- rt_uint8_t ucd_coherent;
+ rt_size_t ucd_size; /* RT_UFS_UCD_SIZE or platform value */
+ rt_ubase_t ucd_handle;
+ rt_uint8_t ucd_coherent;
/* Bounce buffer for small DMA I/O (avoid stack/unmapped buffers) */
rt_uint8_t *bounce;
- rt_size_t bounce_size;
- rt_ubase_t bounce_handle;
+ rt_size_t bounce_size;
+ rt_ubase_t bounce_handle;
/* IRQ status snapshot (written by ISR, read by transfer thread) */
volatile rt_uint32_t irq_status;
struct rt_completion done;
- struct rt_spinlock lock;
+ struct rt_spinlock lock;
struct rt_ufs_pa_layer_attr pwr_active;
- rt_uint8_t pwr_active_valid;
+ rt_uint8_t pwr_active_valid;
/**
* Raw AHIT register value. 0 = use RT_UFS_AHIT_DEFAULT when CAP reports Auto-H8 support.
* Write 0 via rt_ufs_auto_hibern8_set() to turn off auto-hibernate.
@@ -542,6 +534,7 @@ struct rt_ufs_ops
rt_err_t (*init)(struct rt_ufs_host *ufs);
rt_err_t (*exit)(struct rt_ufs_host *ufs);
rt_err_t (*reset)(struct rt_ufs_host *ufs);
+ rt_err_t (*hce_enable_notify)(struct rt_ufs_host *ufs, enum rt_ufs_notify_change_status status);
rt_err_t (*link_startup_notify)(struct rt_ufs_host *ufs, enum rt_ufs_notify_change_status status);
};
@@ -563,7 +556,7 @@ rt_err_t rt_ufs_host_unregister(struct rt_ufs_host *ufs);
* @return RT_EOK on success, -RT_ETIMEOUT on timeout, -RT_ERROR on failure
*/
rt_err_t rt_ufs_uic_cmd_send(struct rt_ufs_host *ufs, rt_uint32_t cmd,
- rt_uint32_t arg1, rt_uint32_t *arg2, rt_uint32_t arg3);
+ rt_uint32_t arg1, rt_uint32_t *arg2, rt_uint32_t arg3);
/**
* @brief Apply default power/performance settings after the link is up
@@ -588,6 +581,16 @@ void rt_ufs_pm_post_linkup(struct rt_ufs_host *ufs);
rt_err_t rt_ufs_dme_set(struct rt_ufs_host *ufs, rt_uint32_t attr_sel, rt_uint32_t value);
/**
+ * @brief UIC DME_RESET
+ */
+rt_err_t rt_ufs_dme_reset(struct rt_ufs_host *ufs);
+
+/**
+ * @brief UIC DME_ENABLE
+ */
+rt_err_t rt_ufs_dme_enable(struct rt_ufs_host *ufs);
+
+/**
* @brief UIC DME_GET
*
* @param ufs UFS host controller
diff --git a/components/drivers/ufs/ufs.c b/components/drivers/ufs/ufs.c
index 9c35e32f9e..73f39c208a 100755
--- a/components/drivers/ufs/ufs.c
+++ b/components/drivers/ufs/ufs.c
@@ -20,20 +20,110 @@
#include <rtdbg.h>
/* UTP slot index used for all SCSI commands (single-threaded transfer) */
-#define RT_UFS_SLOT_ID 0
+#define RT_UFS_SLOT_ID 0
/* Timeout for UTP transfer completion (ms) */
-#define RT_UFS_UTP_TIMEOUT_MS 5000
+#define RT_UFS_UTP_TIMEOUT_MS 5000
/* UIC command timeout (ms) */
-#define RT_UFS_UIC_TIMEOUT_MS 500
+#define RT_UFS_UIC_TIMEOUT_MS 500
/* UTRL/UTMRL base address must be 1KB aligned (UTRLBA/UTMRLBA bits[31:10]). */
-#define RT_UFS_UTR_LIST_ALIGN 1024
-#define RT_UFS_UTR_LIST_BYTES(n) ((rt_size_t)(n) * sizeof(struct rt_utp_transfer_req_desc))
+#define RT_UFS_UTR_LIST_ALIGN 1024
+#define RT_UFS_UTR_LIST_BYTES(n) ((rt_size_t)(n) * sizeof(struct rt_utp_transfer_req_desc))
/* UTRD dword_0 data direction bits */
-#define RT_UFS_UTRD_DD_NONE 0x00000000U
-#define RT_UFS_UTRD_DD_HOST_TO_DEVICE 0x02000000U
-#define RT_UFS_UTRD_DD_DEVICE_TO_HOST 0x04000000U
+#define RT_UFS_UTRD_DD_NONE 0x00000000U
+#define RT_UFS_UTRD_DD_HOST_TO_DEVICE 0x02000000U
+#define RT_UFS_UTRD_DD_DEVICE_TO_HOST 0x04000000U
/* UTRD dword_0 command type bits */
-#define RT_UFS_UTRD_CMD_TYPE_SCSI (1U << RT_UFS_UPIU_COMMAND_TYPE_OFFSET)
+#define RT_UFS_UTRD_CMD_TYPE_SCSI (1U << RT_UFS_UPIU_COMMAND_TYPE_OFFSET)
+
+static rt_err_t ufs_wait_hce(struct rt_ufs_host *ufs)
+{
+ rt_tick_t deadline = rt_tick_get() + rt_tick_from_millisecond(1000);
+
+ while (!(HWREG32(ufs->regs + RT_UFS_REG_HCE) & 0x1))
+ {
+ if (rt_tick_get() >= deadline)
+ {
+ LOG_E("%s: UFS HCE enable timeout", rt_dm_dev_get_name(ufs->parent.dev));
+ return -RT_ETIMEOUT;
+ }
+
+ rt_thread_mdelay(1);
+ }
+
+ return RT_EOK;
+}
+
+static rt_err_t ufs_link_startup(struct rt_ufs_host *ufs)
+{
+ rt_err_t err;
+ rt_uint32_t value = 0;
+
+ if (ufs->ops->link_startup_notify)
+ {
+ ufs->ops->link_startup_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_PRE);
+ }
+
+ err = rt_ufs_uic_cmd_send(ufs, RT_UFS_CMDOP_DME_LINKSTARTUP, 0, &value, 0);
+
+ if (ufs->ops->link_startup_notify)
+ {
+ ufs->ops->link_startup_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_POST);
+ }
+
+ return err;
+}
+
+static rt_err_t ufs_wait_utrd_complete(struct rt_ufs_host *ufs, rt_tick_t timeout)
+{
+ rt_tick_t deadline = rt_tick_get() + timeout;
+ rt_bool_t db_seen = RT_FALSE;
+
+ while (rt_tick_get() < deadline)
+ {
+ rt_base_t level;
+ rt_uint32_t irq_status;
+ rt_uint32_t is = HWREG32(ufs->regs + RT_UFS_REG_IS);
+ rt_uint32_t db = HWREG32(ufs->regs + RT_UFS_REG_UTRLDBR);
+
+ if (db & RT_BIT(RT_UFS_SLOT_ID))
+ {
+ db_seen = RT_TRUE;
+ }
+
+ level = rt_spin_lock_irqsave(&ufs->lock);
+ irq_status = ufs->irq_status;
+
+ if ((irq_status | is) & RT_UFS_REG_IS_UTRCS)
+ {
+ ufs->irq_status &= ~RT_UFS_REG_IS_UTRCS;
+ rt_spin_unlock_irqrestore(&ufs->lock, level);
+ HWREG32(ufs->regs + RT_UFS_REG_IS) = RT_UFS_REG_IS_UTRCS;
+ return RT_EOK;
+ }
+
+ rt_spin_unlock_irqrestore(&ufs->lock, level);
+
+ if (db_seen && !(db & RT_BIT(RT_UFS_SLOT_ID)))
+ {
+ return RT_EOK;
+ }
+
+ if ((irq_status | is) & (RT_UFS_REG_IS_UTPES | RT_UFS_REG_IS_DFES | RT_UFS_REG_IS_UE))
+ {
+ return -RT_ERROR;
+ }
+
+ rt_thread_mdelay(1);
+ }
+
+ return -RT_ETIMEOUT;
+}
+
+static rt_uint8_t ufs_utrd_ocs(struct rt_ufs_host *ufs)
+{
+ rt_hw_cpu_dcache_ops(RT_HW_CACHE_INVALIDATE, ufs->utrd, sizeof(*ufs->utrd));
+ return rt_le32_to_cpu(ufs->utrd->header.dword_2) & 0xf;
+}
static rt_uint8_t ufs_scsi_cmd_data_dir(struct rt_scsi_cmd *cmd)
{
@@ -57,11 +147,11 @@ static rt_uint8_t ufs_scsi_cmd_data_dir(struct rt_scsi_cmd *cmd)
}
static void ufs_prepare_upiu_cmd(struct rt_ufs_host *ufs, struct rt_utp_upiu_req *req, struct rt_utp_upiu_rsp *rsp,
- struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd)
+ struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd)
{
rt_uint16_t cdb_len;
- rt_size_t data_len = cmd->data.size;
- rt_uint8_t flags = RT_UPIU_CMD_FLAGS_NONE;
+ rt_size_t data_len = cmd->data.size;
+ rt_uint8_t flags = RT_UPIU_CMD_FLAGS_NONE;
if (ufs_scsi_cmd_data_dir(cmd) == RT_UTP_DEVICE_TO_HOST)
{
@@ -73,15 +163,15 @@ static void ufs_prepare_upiu_cmd(struct rt_ufs_host *ufs, struct rt_utp_upiu_req
}
rt_memset(req, 0, sizeof(*req));
- req->header.transaction_code = RT_UPIU_TRANSACTION_COMMAND;
- req->header.flags = flags;
- req->header.lun = (rt_uint8_t)(sdev->lun & 0x7f);
- req->header.task_tag = RT_UFS_SLOT_ID;
- req->header.command_set_type = RT_UPIU_COMMAND_SET_TYPE_SCSI;
+ req->header.transaction_code = RT_UPIU_TRANSACTION_COMMAND;
+ req->header.flags = flags;
+ req->header.lun = (rt_uint8_t)(sdev->lun & 0x7f);
+ req->header.task_tag = RT_UFS_SLOT_ID;
+ req->header.command_set_type = RT_UPIU_COMMAND_SET_TYPE_SCSI;
req->header.data_segment_length = rt_cpu_to_be16((rt_uint16_t)data_len);
req->sc.exp_data_transfer_len = rt_cpu_to_be32((rt_uint32_t)data_len);
- cdb_len = cmd->op_size < RT_UFS_CDB_SIZE ? (rt_uint16_t)cmd->op_size : RT_UFS_CDB_SIZE;
+ cdb_len = cmd->op_size < RT_UFS_CDB_SIZE ? (rt_uint16_t)cmd->op_size : RT_UFS_CDB_SIZE;
rt_memcpy(req->sc.cdb, &cmd->op, cdb_len);
rt_memset(rsp, 0, sizeof(*rsp));
@@ -90,18 +180,18 @@ static void ufs_prepare_upiu_cmd(struct rt_ufs_host *ufs, struct rt_utp_upiu_req
/* Fill UTRD header and link to UCD; PRDT filled separately. */
static rt_err_t ufs_prepare_utrd(struct rt_ufs_host *ufs, rt_uint8_t data_dir, rt_size_t data_len)
{
- rt_uint64_t ucd_phys = ufs->ucd_handle;
- rt_uint32_t utp_dd_dword = RT_UFS_UTRD_DD_NONE;
- rt_uint16_t resp_off_dw, resp_len_dw, prdt_off_dw, prdt_len_entries;
+ rt_uint64_t ucd_phys = ufs->ucd_handle;
+ rt_uint32_t utp_dd_dword = RT_UFS_UTRD_DD_NONE;
+ rt_uint16_t resp_off_dw, resp_len_dw, prdt_off_dw, prdt_len_entries;
struct rt_utp_transfer_req_desc *utrd = ufs->utrd;
/* Clear whole descriptor to avoid any leftover fields */
rt_memset(utrd, 0, sizeof(*utrd));
/* UFSHCI: offset/length in DWORDs (4 bytes) */
- resp_off_dw = (rt_uint16_t)(RT_UFS_ALIGNED_UPIU_SIZE >> 2);
- prdt_off_dw = (rt_uint16_t)((RT_UFS_ALIGNED_UPIU_SIZE * 2) >> 2);
- resp_len_dw = (rt_uint16_t)(RT_UFS_ALIGNED_UPIU_SIZE >> 2);
+ resp_off_dw = (rt_uint16_t)(RT_UFS_ALIGNED_UPIU_SIZE >> 2);
+ prdt_off_dw = (rt_uint16_t)((RT_UFS_ALIGNED_UPIU_SIZE * 2) >> 2);
+ resp_len_dw = (rt_uint16_t)(RT_UFS_ALIGNED_UPIU_SIZE >> 2);
prdt_len_entries = (data_len > 0) ? 1 : 0;
/* RequestDescHeader.dword_0..dword_3 */
@@ -123,10 +213,10 @@ static rt_err_t ufs_prepare_utrd(struct rt_ufs_host *ufs, rt_uint8_t data_dir, r
/* UFSHCI expects LE for descriptor fields */
utrd->command_desc_base_addr_lo = rt_cpu_to_le32(rt_lower_32_bits(ucd_phys));
utrd->command_desc_base_addr_hi = rt_cpu_to_le32(rt_upper_32_bits(ucd_phys));
- utrd->response_upiu_offset = rt_cpu_to_le16(resp_off_dw);
- utrd->response_upiu_length = rt_cpu_to_le16(resp_len_dw);
- utrd->prd_table_offset = rt_cpu_to_le16(prdt_off_dw);
- utrd->prd_table_length = rt_cpu_to_le16(prdt_len_entries);
+ utrd->response_upiu_offset = rt_cpu_to_le16(resp_off_dw);
+ utrd->response_upiu_length = rt_cpu_to_le16(resp_len_dw);
+ utrd->prd_table_offset = rt_cpu_to_le16(prdt_off_dw);
+ utrd->prd_table_length = rt_cpu_to_le16(prdt_len_entries);
return RT_EOK;
}
@@ -134,11 +224,11 @@ static rt_err_t ufs_prepare_utrd(struct rt_ufs_host *ufs, rt_uint8_t data_dir, r
/* Fill PRDT with entries for cmd->data.ptr (split by page boundary). */
static rt_err_t ufs_prepare_prdt(struct rt_ufs_host *ufs, const void *data_ptr, rt_size_t len, rt_uint16_t *out_entries)
{
- rt_size_t left;
- rt_uint8_t *ptr;
- rt_uint16_t n = 0;
+ rt_size_t left;
+ rt_uint8_t *ptr;
+ rt_uint16_t n = 0;
struct rt_utp_transfer_cmd_desc *ucd = (struct rt_utp_transfer_cmd_desc *)ufs->ucd_base;
- struct rt_ufs_sg_entry *prd = ucd->prd_table;
+ struct rt_ufs_sg_entry *prd = ucd->prd_table;
if (out_entries)
{
@@ -151,22 +241,22 @@ static rt_err_t ufs_prepare_prdt(struct rt_ufs_host *ufs, const void *data_ptr,
}
left = len;
- ptr = (rt_uint8_t *)(rt_ubase_t)data_ptr;
+ ptr = (rt_uint8_t *)(rt_ubase_t)data_ptr;
while (left)
{
rt_uint64_t addr;
- rt_size_t chunk, page_off;
+ rt_size_t chunk, page_off;
if (n >= RT_UFS_PRDT_ENTRIES_PER_SLOT)
{
LOG_E("%s: UFS: PRDT entries overflow (len=%u left=%u n=%u)", rt_dm_dev_get_name(ufs->parent.dev),
- len, left, n);
+ len, left, n);
return -RT_EIO;
}
page_off = ((rt_ubase_t)ptr) & (ARCH_PAGE_SIZE - 1);
- chunk = ARCH_PAGE_SIZE - page_off;
+ chunk = ARCH_PAGE_SIZE - page_off;
if (chunk > left)
{
chunk = left;
@@ -181,11 +271,11 @@ static rt_err_t ufs_prepare_prdt(struct rt_ufs_host *ufs, const void *data_ptr,
addr = (rt_uint64_t)rt_kmem_v2p(ptr);
}
- prd[n].addr = rt_cpu_to_le64(addr);
+ prd[n].addr = rt_cpu_to_le64(addr);
prd[n].reserved = 0;
- prd[n].size = rt_cpu_to_le32((rt_uint32_t)(chunk - 1)); /* 0-based byte count */
+ prd[n].size = rt_cpu_to_le32((rt_uint32_t)(chunk - 1)); /* 0-based byte count */
- ptr += chunk;
+ ptr += chunk;
left -= chunk;
++n;
}
@@ -200,22 +290,24 @@ static rt_err_t ufs_prepare_prdt(struct rt_ufs_host *ufs, const void *data_ptr,
static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd)
{
- struct rt_utp_transfer_cmd_desc *ucd = (struct rt_utp_transfer_cmd_desc *)ufs->ucd_base;
- struct rt_utp_upiu_req *req = (struct rt_utp_upiu_req *)ucd->command_upiu;
- struct rt_utp_upiu_rsp *rsp = (struct rt_utp_upiu_rsp *)ucd->response_upiu;
+ struct rt_utp_transfer_cmd_desc *ucd = (struct rt_utp_transfer_cmd_desc *)ufs->ucd_base;
+ struct rt_utp_upiu_req *req = (struct rt_utp_upiu_req *)ucd->command_upiu;
+ struct rt_utp_upiu_rsp *rsp = (struct rt_utp_upiu_rsp *)ucd->response_upiu;
struct rt_utp_transfer_req_desc *utrd = ufs->utrd;
- void *regs = ufs->regs;
- rt_uint8_t data_dir;
- rt_uint32_t is;
- rt_err_t err = RT_EOK;
- rt_uint16_t prdt_entries = 0;
- rt_uint8_t ocs;
- rt_bool_t use_bounce = RT_FALSE;
- void *orig_ptr = cmd->data.ptr, *resp_buf;
- rt_size_t orig_size = cmd->data.size;
- void *dma_ptr = cmd->data.ptr;
- rt_size_t dma_size = cmd->data.size;
- rt_bool_t bounce_copied = RT_FALSE;
+ void *regs = ufs->regs;
+ rt_uint8_t data_dir;
+ rt_base_t level;
+ rt_uint32_t is;
+ rt_uint32_t irq_status;
+ rt_err_t err = RT_EOK;
+ rt_uint16_t prdt_entries = 0;
+ rt_uint8_t ocs;
+ rt_bool_t use_bounce = RT_FALSE;
+ void *orig_ptr = cmd->data.ptr, *resp_buf;
+ rt_size_t orig_size = cmd->data.size;
+ void *dma_ptr = cmd->data.ptr;
+ rt_size_t dma_size = cmd->data.size;
+ rt_bool_t bounce_copied = RT_FALSE;
data_dir = ufs_scsi_cmd_data_dir(cmd);
/* Basic controller readiness checks to avoid hard timeouts */
@@ -250,7 +342,7 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device
{
rt_memcpy(ufs->bounce, orig_ptr, orig_size);
}
- dma_ptr = ufs->bounce;
+ dma_ptr = ufs->bounce;
dma_size = orig_size;
}
@@ -268,31 +360,31 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device
/* Basic debug information before submitting UTP */
LOG_D("%s: UTP submit: opcode=%#02x dir=%u data_len=%u slot=%u",
- rt_dm_dev_get_name(ufs->parent.dev),
- cmd->op.unknow.opcode, data_dir,
- cmd->data.size, RT_UFS_SLOT_ID);
+ rt_dm_dev_get_name(ufs->parent.dev),
+ cmd->op.unknow.opcode, data_dir,
+ cmd->data.size, RT_UFS_SLOT_ID);
LOG_D("%s: UTP ctrl regs: HCS=%#08x IE=%#08x HCE=%#08x",
- rt_dm_dev_get_name(ufs->parent.dev),
- HWREG32(regs + RT_UFS_REG_HCS),
- HWREG32(regs + RT_UFS_REG_IE),
- HWREG32(regs + RT_UFS_REG_HCE));
+ rt_dm_dev_get_name(ufs->parent.dev),
+ HWREG32(regs + RT_UFS_REG_HCS),
+ HWREG32(regs + RT_UFS_REG_IE),
+ HWREG32(regs + RT_UFS_REG_HCE));
LOG_D("%s: UTP ctrl ready bits: UTRLRDY=%u UTMRLRDY=%u UICRDY=%u",
- rt_dm_dev_get_name(ufs->parent.dev),
- (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UTRLRDY) ? 1 : 0,
- (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UTMRLRDY) ? 1 : 0,
- (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UCRDY) ? 1 : 0);
+ rt_dm_dev_get_name(ufs->parent.dev),
+ (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UTRLRDY) ? 1 : 0,
+ (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UTMRLRDY) ? 1 : 0,
+ (HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UCRDY) ? 1 : 0);
LOG_D("%s: UTP UTRD: dword_0=%#08x dword_2(ocs)=%#08x",
- rt_dm_dev_get_name(ufs->parent.dev),
- rt_le32_to_cpu(utrd->header.dword_0),
- rt_le32_to_cpu(utrd->header.dword_2));
+ rt_dm_dev_get_name(ufs->parent.dev),
+ rt_le32_to_cpu(utrd->header.dword_0),
+ rt_le32_to_cpu(utrd->header.dword_2));
LOG_D("%s: UTP UTRD: ucd_base_lo=%#08x ucd_base_hi=%#08x resp_off_dw=%u resp_len_dw=%u prd_off_dw=%u prd_len=%u",
- rt_dm_dev_get_name(ufs->parent.dev),
- rt_le32_to_cpu(utrd->command_desc_base_addr_lo),
- rt_le32_to_cpu(utrd->command_desc_base_addr_hi),
- rt_le16_to_cpu(utrd->response_upiu_offset),
- rt_le16_to_cpu(utrd->response_upiu_length),
- rt_le16_to_cpu(utrd->prd_table_offset),
- rt_le16_to_cpu(utrd->prd_table_length));
+ rt_dm_dev_get_name(ufs->parent.dev),
+ rt_le32_to_cpu(utrd->command_desc_base_addr_lo),
+ rt_le32_to_cpu(utrd->command_desc_base_addr_hi),
+ rt_le16_to_cpu(utrd->response_upiu_offset),
+ rt_le16_to_cpu(utrd->response_upiu_length),
+ rt_le16_to_cpu(utrd->prd_table_offset),
+ rt_le16_to_cpu(utrd->prd_table_length));
/*
* DMA descriptors/data must be visible to controller.
@@ -307,7 +399,9 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device
}
/* Clear interrupt status for transfer complete */
+ level = rt_spin_lock_irqsave(&ufs->lock);
ufs->irq_status = 0;
+ rt_spin_unlock_irqrestore(&ufs->lock, level);
/* Ack any stale pending IRQ bits before kicking */
HWREG32(regs + RT_UFS_REG_IS) = RT_UINT32_MAX;
/* Enable UTP completion/error interrupts */
@@ -318,32 +412,42 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device
HWREG32(regs + RT_UFS_REG_UTRLDBR) = RT_BIT(RT_UFS_SLOT_ID);
rt_spin_unlock(&ufs->lock);
- /* Interrupt mode: wait for completion signaled by ISR */
- if ((err = rt_completion_wait(&ufs->done, rt_tick_from_millisecond(RT_UFS_UTP_TIMEOUT_MS))))
+ /*
+ * Poll UTRCS directly. QEMU and some PCI hosts may complete the transfer
+ * before the INTx/MSI handler is wired up during early probe.
+ */
+ if ((err = ufs_wait_utrd_complete(ufs, rt_tick_from_millisecond(RT_UFS_UTP_TIMEOUT_MS))))
{
- LOG_E("%s: UFS UTP wait timeout: IS=%#08x irq_status=%#08x",
- rt_dm_dev_get_name(ufs->parent.dev),
- HWREG32(regs + RT_UFS_REG_IS), ufs->irq_status);
+ level = rt_spin_lock_irqsave(&ufs->lock);
+ irq_status = ufs->irq_status;
+ rt_spin_unlock_irqrestore(&ufs->lock, level);
+
+ LOG_E("%s: UFS UTP wait failed: err=%d IS=%#08x irq_status=%#08x UTRLDBR=%#08x OCS=%#x",
+ rt_dm_dev_get_name(ufs->parent.dev),
+ err, HWREG32(regs + RT_UFS_REG_IS), irq_status,
+ HWREG32(regs + RT_UFS_REG_UTRLDBR), ufs_utrd_ocs(ufs));
/* Dump UPIU header and PRDT entry for post-mortem */
LOG_E("%s: UTP UPIU: tx=%u flags=%#02x lun=%u tag=%u seg_len(be16)=%u",
- rt_dm_dev_get_name(ufs->parent.dev),
- req->header.transaction_code, req->header.flags,
- req->header.lun, req->header.task_tag,
- rt_be16_to_cpu(req->header.data_segment_length));
+ rt_dm_dev_get_name(ufs->parent.dev),
+ req->header.transaction_code, req->header.flags,
+ req->header.lun, req->header.task_tag,
+ rt_be16_to_cpu(req->header.data_segment_length));
if (cmd->data.size > 0)
{
+ struct rt_ufs_sg_entry *prd = ((struct rt_utp_transfer_cmd_desc *)ufs->ucd_base)->prd_table;
+
LOG_E("%s: UTP PRDT[0]: addr=%#llx size(le32)=%#08x",
- rt_dm_dev_get_name(ufs->parent.dev),
- (rt_uint64_t)(&((struct rt_utp_transfer_cmd_desc *)ufs->ucd_base)->prd_table[0])->addr,
- (&((struct rt_utp_transfer_cmd_desc *)ufs->ucd_base)->prd_table[0])->size);
+ rt_dm_dev_get_name(ufs->parent.dev),
+ (unsigned long long)rt_le64_to_cpu(prd[0].addr),
+ rt_le32_to_cpu(prd[0].size));
}
goto _end;
}
- is = ufs->irq_status | HWREG32(regs + RT_UFS_REG_IS);
+ is = HWREG32(regs + RT_UFS_REG_IS);
if (is & (RT_UFS_REG_IS_UTPES | RT_UFS_REG_IS_DFES | RT_UFS_REG_IS_UE))
{
err = -RT_ERROR;
@@ -372,9 +476,9 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device
}
LOG_D("%s: UFS UTRD complete: dword_2=%#08x (ocs=%#x)",
- rt_dm_dev_get_name(ufs->parent.dev),
- rt_le32_to_cpu(utrd->header.dword_2),
- (rt_le32_to_cpu(utrd->header.dword_2) & 0x0f));
+ rt_dm_dev_get_name(ufs->parent.dev),
+ rt_le32_to_cpu(utrd->header.dword_2),
+ (rt_le32_to_cpu(utrd->header.dword_2) & 0x0f));
/*
* Post-process SCSI response in resp_buf (INQUIRY etc.).
@@ -395,8 +499,8 @@ static rt_err_t ufs_utp_transfer(struct rt_ufs_host *ufs, struct rt_scsi_device
/* Align with AHCI behavior: always expose direct-access block device */
inq->devtype = SCSI_DEVICE_TYPE_DIRECT;
- inq->rmb = 0;
- inq->length = 95 - 4;
+ inq->rmb = 0;
+ inq->length = 95 - 4;
}
_no_resp_buf:
@@ -423,8 +527,16 @@ _no_resp_buf:
goto _end;
}
- if (rsp->header.status != 0)
+ /*
+ * SCSI status lives in the response UPIU header. CHECK CONDITION (0x02)
+ * may still carry valid data; sense is handled by the SCSI core if needed.
+ */
+ if (rsp->header.status != 0 && rsp->header.status != 0x02)
{
+ LOG_E("%s: UFS SCSI status=%#02x sense_len=%u",
+ rt_dm_dev_get_name(ufs->parent.dev),
+ rsp->header.status,
+ rt_be16_to_cpu(rsp->sr.sense_data_len));
err = -RT_ERROR;
goto _end;
}
@@ -461,7 +573,7 @@ static rt_err_t ufs_host_reset(struct rt_scsi_device *sdev)
static rt_err_t ufs_host_transfer(struct rt_scsi_device *sdev, struct rt_scsi_cmd *cmd)
{
- rt_err_t err;
+ rt_err_t err;
struct rt_ufs_host *ufs = rt_container_of(sdev->host, struct rt_ufs_host, parent);
switch (cmd->op.unknow.opcode)
@@ -499,15 +611,14 @@ static rt_err_t ufs_host_transfer(struct rt_scsi_device *sdev, struct rt_scsi_cm
return err;
}
-static struct rt_scsi_ops ufs_host_ops =
-{
- .reset = ufs_host_reset,
+static struct rt_scsi_ops ufs_host_ops = {
+ .reset = ufs_host_reset,
.transfer = ufs_host_transfer,
};
static void ufs_isr(int irqno, void *param)
{
- rt_uint32_t is;
+ rt_uint32_t is;
struct rt_ufs_host *ufs = param;
if (!(is = HWREG32(ufs->regs + RT_UFS_REG_IS)))
@@ -515,7 +626,9 @@ static void ufs_isr(int irqno, void *param)
return;
}
+ rt_spin_lock(&ufs->lock);
ufs->irq_status |= is;
+ rt_spin_unlock(&ufs->lock);
HWREG32(ufs->regs + RT_UFS_REG_IS) = is;
if (is & (RT_UFS_REG_IS_UTRCS | RT_UFS_REG_IS_UTPES | RT_UFS_REG_IS_DFES | RT_UFS_REG_IS_UE))
@@ -526,9 +639,8 @@ static void ufs_isr(int irqno, void *param)
rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs)
{
- rt_err_t err;
- rt_uint32_t value;
- char dev_name[RT_NAME_MAX];
+ rt_err_t err;
+ char dev_name[RT_NAME_MAX];
struct rt_scsi_host *scsi;
if (!ufs || !ufs->ops || !ufs->regs)
@@ -536,7 +648,7 @@ rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs)
return -RT_EINVAL;
}
- ufs->cap = HWREG32(ufs->regs + RT_UFS_REG_CAP);
+ ufs->cap = HWREG32(ufs->regs + RT_UFS_REG_CAP);
ufs->nutrs = RT_UFS_REG_CAP_NUTRS(ufs->cap) + 1;
ufs->nutrs = rt_min_t(rt_uint32_t, 32, ufs->nutrs);
@@ -555,7 +667,7 @@ rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs)
ufs->utrd = (struct rt_utp_transfer_req_desc *)ufs->utrl_base; /* Slot0 */
/* Allocate UCD (Command Descriptor) */
- ufs->ucd_size = ufs->ucd_size ? : RT_UFS_UCD_SIZE;
+ ufs->ucd_size = ufs->ucd_size ?: RT_UFS_UCD_SIZE;
ufs->ucd_base = rt_dma_alloc_coherent(ufs->parent.dev, ufs->ucd_size, &ufs->ucd_handle);
if (!ufs->ucd_base)
@@ -567,9 +679,9 @@ rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs)
rt_memset(ufs->ucd_base, 0, ufs->ucd_size);
/* Allocate bounce buffer for small DMA transfers (512B is enough for inquiry/sense/capacity) */
- ufs->bounce_size = 4096;
+ ufs->bounce_size = 4096;
ufs->bounce_handle = 0;
- ufs->bounce = rt_dma_alloc_coherent(ufs->parent.dev, ufs->bounce_size, &ufs->bounce_handle);
+ ufs->bounce = rt_dma_alloc_coherent(ufs->parent.dev, ufs->bounce_size, &ufs->bounce_handle);
if (!ufs->bounce)
{
@@ -585,50 +697,52 @@ rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs)
goto _fail;
}
+ if (ufs->ops->hce_enable_notify &&
+ (err = ufs->ops->hce_enable_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_PRE)))
+ {
+ goto _fail;
+ }
+
/* Enable controller (HCE 1) */
HWREG32(ufs->regs + RT_UFS_REG_HCE) = 0;
rt_thread_mdelay(1);
HWREG32(ufs->regs + RT_UFS_REG_HCE) = 0x1;
- rt_thread_mdelay(1);
+
+ if ((err = ufs_wait_hce(ufs)))
+ {
+ goto _fail;
+ }
/* Program UTRD/UTMRD list base addresses */
- HWREG32(ufs->regs + RT_UFS_REG_UTRLBA) = rt_lower_32_bits(ufs->utrl_handle);
+ HWREG32(ufs->regs + RT_UFS_REG_UTRLBA) = rt_lower_32_bits(ufs->utrl_handle);
HWREG32(ufs->regs + RT_UFS_REG_UTRLBAU) = rt_upper_32_bits(ufs->utrl_handle);
/* UTMRL: allocate minimal aligned list if not provided */
- ufs->utmrl_size = RT_UFS_UTR_LIST_ALIGN;
+ ufs->utmrl_size = RT_UFS_UTR_LIST_ALIGN;
ufs->utmrl_handle = 0;
- ufs->utmrl_base = rt_dma_alloc_coherent(ufs->parent.dev, ufs->utmrl_size, &ufs->utmrl_handle);
+ ufs->utmrl_base = rt_dma_alloc_coherent(ufs->parent.dev, ufs->utmrl_size, &ufs->utmrl_handle);
if (ufs->utmrl_base)
{
rt_memset(ufs->utmrl_base, 0, ufs->utmrl_size);
}
- HWREG32(ufs->regs + RT_UFS_REG_UTMRLBA) = rt_lower_32_bits(ufs->utmrl_handle);
+ HWREG32(ufs->regs + RT_UFS_REG_UTMRLBA) = rt_lower_32_bits(ufs->utmrl_handle);
HWREG32(ufs->regs + RT_UFS_REG_UTMRLBAU) = rt_upper_32_bits(ufs->utmrl_handle);
/* Start run/stop */
- HWREG32(ufs->regs + RT_UFS_REG_UTRLRSR) = 0x1;
+ HWREG32(ufs->regs + RT_UFS_REG_UTRLRSR) = 0x1;
HWREG32(ufs->regs + RT_UFS_REG_UTMRLRSR) = 0x1;
- /* Link startup: set UTRLRDY/UTMRLRDY */
- value = HWREG32(ufs->regs + RT_UFS_REG_HCS);
- if (!(value & RT_UFS_REG_HCS_UTRLRDY) || !(value & RT_UFS_REG_HCS_UTMRLRDY) || !(value & RT_UFS_REG_HCS_UCRDY))
+ if (ufs->ops->hce_enable_notify &&
+ (err = ufs->ops->hce_enable_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_POST)))
{
- if (ufs->ops->link_startup_notify)
- {
- ufs->ops->link_startup_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_PRE);
- }
-
- if ((err = rt_ufs_uic_cmd_send(ufs, RT_UFS_CMDOP_DME_LINKSTARTUP, 0, &value, 0)))
- {
- goto _fail;
- }
+ goto _fail;
+ }
- if (ufs->ops->link_startup_notify)
- {
- ufs->ops->link_startup_notify(ufs, RT_UFS_NOTIFY_CHANGE_STATUS_POST);
- }
+ /* Link startup: required before the first SCSI/UTP transfer */
+ if ((err = ufs_link_startup(ufs)))
+ {
+ goto _fail;
}
ufs->pwr_active_valid = 0;
@@ -643,10 +757,10 @@ rt_err_t rt_ufs_host_register(struct rt_ufs_host *ufs)
rt_hw_interrupt_install(ufs->irq, ufs_isr, ufs, dev_name);
rt_hw_interrupt_umask(ufs->irq);
- scsi = &ufs->parent;
- scsi->ops = &ufs_host_ops;
- scsi->max_id = rt_max_t(rt_size_t, scsi->max_id, 1);
- scsi->max_lun = rt_max_t(rt_size_t, scsi->max_lun, 1);
+ scsi = &ufs->parent;
+ scsi->ops = &ufs_host_ops;
+ scsi->max_id = rt_max_t(rt_size_t, scsi->max_id, 1);
+ scsi->max_lun = rt_max_t(rt_size_t, scsi->max_lun, 1);
scsi->parallel_io = RT_TRUE;
if ((err = rt_scsi_host_register(scsi)))
@@ -721,18 +835,18 @@ rt_err_t rt_ufs_host_unregister(struct rt_ufs_host *ufs)
}
rt_err_t rt_ufs_uic_cmd_send(struct rt_ufs_host *ufs, rt_uint32_t cmd,
- rt_uint32_t arg1, rt_uint32_t *arg2, rt_uint32_t arg3)
+ rt_uint32_t arg1, rt_uint32_t *arg2, rt_uint32_t arg3)
{
rt_uint32_t is;
- rt_int32_t timeout;
- void *regs = ufs->regs;
+ rt_int32_t timeout;
+ void *regs = ufs->regs;
if (!regs)
{
return -RT_EINVAL;
}
- timeout = rt_tick_from_millisecond(RT_UFS_UIC_TIMEOUT_MS);
+ timeout = rt_tick_from_millisecond(RT_UFS_UIC_TIMEOUT_MS);
timeout += rt_tick_get();
while (!(HWREG32(regs + RT_UFS_REG_HCS) & RT_UFS_REG_HCS_UCRDY))
@@ -749,12 +863,13 @@ rt_err_t rt_ufs_uic_cmd_send(struct rt_ufs_host *ufs, rt_uint32_t cmd,
HWREG32(regs + RT_UFS_REG_UCMDARG1) = arg1;
HWREG32(regs + RT_UFS_REG_UCMDARG2) = arg2 ? *arg2 : 0;
HWREG32(regs + RT_UFS_REG_UCMDARG3) = arg3;
- HWREG32(regs + RT_UFS_REG_UICCMD) = cmd & 0xff;
+ HWREG32(regs + RT_UFS_REG_UICCMD) = cmd & 0xff;
- timeout = rt_tick_from_millisecond(RT_UFS_UIC_TIMEOUT_MS);
+ timeout = rt_tick_from_millisecond(RT_UFS_UIC_TIMEOUT_MS);
timeout += rt_tick_get();
- do {
+ do
+ {
is = HWREG32(regs + RT_UFS_REG_IS);
if (is & RT_UFS_REG_IS_UCCS)
{
diff --git a/components/drivers/ufs/ufs_pm.c b/components/drivers/ufs/ufs_pm.c
index 86284efee0..acd0d1d018 100755
--- a/components/drivers/ufs/ufs_pm.c
+++ b/components/drivers/ufs/ufs_pm.c
@@ -18,7 +18,7 @@
#define DBG_LVL DBG_INFO
#include <rtdbg.h>
-#define RT_UFS_DME_ATTR_SET_NOR 0
+#define RT_UFS_DME_ATTR_SET_NOR 0
rt_inline rt_uint32_t ufs_uic_arg_attr_type(rt_uint8_t t)
{
@@ -27,7 +27,7 @@ rt_inline rt_uint32_t ufs_uic_arg_attr_type(rt_uint8_t t)
rt_err_t rt_ufs_dme_set(struct rt_ufs_host *ufs, rt_uint32_t attr_sel, rt_uint32_t value)
{
- rt_err_t err;
+ rt_err_t err;
rt_uint32_t arg2 = ufs_uic_arg_attr_type(RT_UFS_DME_ATTR_SET_NOR);
if ((err = rt_ufs_uic_cmd_send(ufs, RT_UFS_CMDOP_DME_SET, attr_sel, &arg2, value)))
@@ -43,10 +43,46 @@ rt_err_t rt_ufs_dme_set(struct rt_ufs_host *ufs, rt_uint32_t attr_sel, rt_uint32
return RT_EOK;
}
+rt_err_t rt_ufs_dme_reset(struct rt_ufs_host *ufs)
+{
+ rt_err_t err;
+ rt_uint32_t arg2 = 0;
+
+ if ((err = rt_ufs_uic_cmd_send(ufs, RT_UFS_CMDOP_DME_RESET, 0, &arg2, 0)))
+ {
+ return err;
+ }
+
+ if ((arg2 & RT_UFS_CMDRES_MASK) != RT_UFS_CMDRES_SUCCESS)
+ {
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
+rt_err_t rt_ufs_dme_enable(struct rt_ufs_host *ufs)
+{
+ rt_err_t err;
+ rt_uint32_t arg2 = 0;
+
+ if ((err = rt_ufs_uic_cmd_send(ufs, RT_UFS_CMDOP_DME_ENABLE, 0, &arg2, 0)))
+ {
+ return err;
+ }
+
+ if ((arg2 & RT_UFS_CMDRES_MASK) != RT_UFS_CMDRES_SUCCESS)
+ {
+ return -RT_ERROR;
+ }
+
+ return RT_EOK;
+}
+
rt_err_t rt_ufs_dme_get(struct rt_ufs_host *ufs, rt_uint32_t attr_sel, rt_uint32_t *value)
{
rt_uint32_t arg2 = 0;
- rt_err_t err;
+ rt_err_t err;
if (!value)
{
@@ -75,7 +111,7 @@ rt_err_t rt_ufs_uic_pa_pwrmode(struct rt_ufs_host *ufs, rt_uint8_t mode)
rt_err_t rt_ufs_pa_power_mode_set(struct rt_ufs_host *ufs, const struct rt_ufs_pa_layer_attr *attr, rt_bool_t force)
{
- rt_err_t err;
+ rt_err_t err;
rt_uint8_t mode;
if (!ufs || !attr || !ufs->regs)
@@ -192,7 +228,7 @@ rt_err_t rt_ufs_pa_power_mode_set(struct rt_ufs_host *ufs, const struct rt_ufs_p
return err;
}
- ufs->pwr_active = *attr;
+ ufs->pwr_active = *attr;
ufs->pwr_active_valid = 1;
return RT_EOK;
@@ -255,7 +291,7 @@ rt_err_t rt_ufs_auto_hibern8_set(struct rt_ufs_host *ufs, rt_uint32_t reg_val)
}
HWREG32(ufs->regs + RT_UFS_REG_AHIT) = reg_val;
- ufs->ahit = reg_val;
+ ufs->ahit = reg_val;
return RT_EOK;
}