]> git.baikalelectronics.ru Git - arm-tf.git/commitdiff
fix(ufs): set the PRDT length field properly
authorJorge Troncoso <jatron@google.com>
Wed, 22 Feb 2023 23:30:47 +0000 (15:30 -0800)
committerJorge Troncoso <jatron@google.com>
Sat, 25 Feb 2023 14:32:44 +0000 (06:32 -0800)
The PRDT length field contains the count of the entries in the PRDT. See
JEDEC Standard No. 223E, section 6.1.1, "UTP Transfer Request
Descriptor," page 66. Previously we were setting the PRDT length field
to the number of bytes in the PRDT divided by four (the size in units of
32 bits). This was incorrect according to the spec.

Signed-off-by: Jorge Troncoso <jatron@google.com>
Change-Id: I960771e6ce57002872392993042fae9ec505447e

drivers/ufs/ufs.c
include/drivers/ufs.h

index 1fe0b0e1f19ca112dd0706f0e1a156bc522aeea6..60743740e44433387bfcd96b0d19f5fc29fce428 100644 (file)
@@ -288,9 +288,8 @@ static int ufs_prepare_cmd(utp_utrd_t *utrd, uint8_t op, uint8_t lun,
        prdt_t *prdt;
        unsigned int ulba;
        unsigned int lba_cnt;
-       int prdt_size;
        uintptr_t desc_limit;
-       size_t flush_size;
+       uintptr_t prdt_end;
 
        hd = (utrd_header_t *)utrd->header;
        upiu = (cmd_upiu_t *)utrd->upiu;
@@ -350,14 +349,13 @@ static int ufs_prepare_cmd(utp_utrd_t *utrd, uint8_t op, uint8_t lun,
                inv_dcache_range(buf, length);
        }
 
-       utrd->size_prdt = 0;
+       utrd->prdt_length = 0;
        if (length) {
                upiu->exp_data_trans_len = htobe32(length);
                assert(lba_cnt <= UINT16_MAX);
                prdt = (prdt_t *)utrd->prdt;
 
                desc_limit = ufs_params.desc_base + ufs_params.desc_size;
-               prdt_size = 0;
                while (length > 0) {
                        if ((uintptr_t)prdt + sizeof(prdt_t) > desc_limit) {
                                ERROR("UFS: Exceeded descriptor limit. Image is too large\n");
@@ -375,15 +373,14 @@ static int ufs_prepare_cmd(utp_utrd_t *utrd, uint8_t op, uint8_t lun,
                        }
                        buf += MAX_PRDT_SIZE;
                        prdt++;
-                       prdt_size += sizeof(prdt_t);
+                       utrd->prdt_length++;
                }
-               utrd->size_prdt = ALIGN_8(prdt_size);
-               hd->prdtl = utrd->size_prdt >> 2;
+               hd->prdtl = utrd->prdt_length;
                hd->prdto = (utrd->size_upiu + utrd->size_resp_upiu) >> 2;
        }
 
-       flush_size = utrd->prdt + utrd->size_prdt - utrd->header;
-       flush_dcache_range(utrd->header, flush_size);
+       prdt_end = utrd->prdt + utrd->prdt_length * sizeof(prdt_t);
+       flush_dcache_range(utrd->header, prdt_end - utrd->header);
        return 0;
 }
 
index 1cd1beeeed7e7884420337cde862fec4eb86efde..e4ec00d5c9d618cf5e0e39c8e9bd13031af88168 100644 (file)
@@ -519,7 +519,7 @@ typedef struct utp_utrd {
        uintptr_t       prdt;
        size_t          size_upiu;
        size_t          size_resp_upiu;
-       size_t          size_prdt;
+       size_t          prdt_length;
        int             task_tag;
 } utp_utrd_t;