lkml.org 
[lkml]   [2020]   [Aug]   [24]   [last100]   RSS Feed
Views: [wrap][no wrap]   [headers]  [forward] 
 
Messages in this thread
    Patch in this message
    /
    From
    Subject[PATCH 5.7 096/124] scsi: ufs: Introduce UFSHCD_QUIRK_PRDT_BYTE_GRAN quirk
    Date
    From: Alim Akhtar <alim.akhtar@samsung.com>

    [ Upstream commit 26f968d7de823ba4974a8f25c8bd8ee2df6ab74b ]

    Some UFS host controllers like Exynos uses granularities of PRDT length and
    offset as bytes, whereas others use actual segment count.

    Link: https://lore.kernel.org/r/20200528011658.71590-5-alim.akhtar@samsung.com
    Reviewed-by: Avri Altman <avri.altman@wdc.com>
    Signed-off-by: Kiwoong Kim <kwmad.kim@samsung.com>
    Signed-off-by: Alim Akhtar <alim.akhtar@samsung.com>
    Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>
    Signed-off-by: Sasha Levin <sashal@kernel.org>
    ---
    drivers/scsi/ufs/ufshcd.c | 30 +++++++++++++++++++++++-------
    drivers/scsi/ufs/ufshcd.h | 6 ++++++
    2 files changed, 29 insertions(+), 7 deletions(-)

    diff --git a/drivers/scsi/ufs/ufshcd.c b/drivers/scsi/ufs/ufshcd.c
    index 3820117795327..4d5e8f6a31438 100644
    --- a/drivers/scsi/ufs/ufshcd.c
    +++ b/drivers/scsi/ufs/ufshcd.c
    @@ -2158,8 +2158,14 @@ static int ufshcd_map_sg(struct ufs_hba *hba, struct ufshcd_lrb *lrbp)
    return sg_segments;

    if (sg_segments) {
    - lrbp->utr_descriptor_ptr->prd_table_length =
    - cpu_to_le16((u16)sg_segments);
    +
    + if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN)
    + lrbp->utr_descriptor_ptr->prd_table_length =
    + cpu_to_le16((sg_segments *
    + sizeof(struct ufshcd_sg_entry)));
    + else
    + lrbp->utr_descriptor_ptr->prd_table_length =
    + cpu_to_le16((u16) (sg_segments));

    prd_table = (struct ufshcd_sg_entry *)lrbp->ucd_prdt_ptr;

    @@ -3505,11 +3511,21 @@ static void ufshcd_host_memory_configure(struct ufs_hba *hba)
    cpu_to_le32(upper_32_bits(cmd_desc_element_addr));

    /* Response upiu and prdt offset should be in double words */
    - utrdlp[i].response_upiu_offset =
    - cpu_to_le16(response_offset >> 2);
    - utrdlp[i].prd_table_offset = cpu_to_le16(prdt_offset >> 2);
    - utrdlp[i].response_upiu_length =
    - cpu_to_le16(ALIGNED_UPIU_SIZE >> 2);
    + if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) {
    + utrdlp[i].response_upiu_offset =
    + cpu_to_le16(response_offset);
    + utrdlp[i].prd_table_offset =
    + cpu_to_le16(prdt_offset);
    + utrdlp[i].response_upiu_length =
    + cpu_to_le16(ALIGNED_UPIU_SIZE);
    + } else {
    + utrdlp[i].response_upiu_offset =
    + cpu_to_le16(response_offset >> 2);
    + utrdlp[i].prd_table_offset =
    + cpu_to_le16(prdt_offset >> 2);
    + utrdlp[i].response_upiu_length =
    + cpu_to_le16(ALIGNED_UPIU_SIZE >> 2);
    + }

    ufshcd_init_lrb(hba, &hba->lrb[i], i);
    }
    diff --git a/drivers/scsi/ufs/ufshcd.h b/drivers/scsi/ufs/ufshcd.h
    index 99dc0ca311899..b3b2d09d8fff3 100644
    --- a/drivers/scsi/ufs/ufshcd.h
    +++ b/drivers/scsi/ufs/ufshcd.h
    @@ -535,6 +535,12 @@ enum ufshcd_quirks {
    * enabled via HCE register.
    */
    UFSHCI_QUIRK_BROKEN_HCE = 1 << 8,
    +
    + /*
    + * This quirk needs to be enabled if the host controller regards
    + * resolution of the values of PRDTO and PRDTL in UTRD as byte.
    + */
    + UFSHCD_QUIRK_PRDT_BYTE_GRAN = 1 << 9,
    };

    enum ufshcd_caps {
    --
    2.25.1


    \
     
     \ /
      Last update: 2020-08-24 10:45    [W:4.105 / U:0.184 seconds]
    ©2003-2020 Jasper Spaans|hosted at Digital Ocean and TransIP|Read the blog|Advertise on this site