diff options
author | Marek Vasut <marek.vasut+renesas@mailbox.org> | 2023-08-16 17:05:50 +0200 |
---|---|---|
committer | Tom Rini <trini@konsulko.com> | 2023-08-24 13:47:43 -0400 |
commit | 91913a1aa2ffeb7278d7d4e4bc51565bb38cebeb (patch) | |
tree | c18fdc49ce578412123db9c80e8401a651c4ab86 /drivers/ufs/ufs.c | |
parent | 5dab730cac673c635a5107a28c0c4288a442f135 (diff) | |
download | u-boot-91913a1aa2ffeb7278d7d4e4bc51565bb38cebeb.zip u-boot-91913a1aa2ffeb7278d7d4e4bc51565bb38cebeb.tar.gz u-boot-91913a1aa2ffeb7278d7d4e4bc51565bb38cebeb.tar.bz2 |
ufs: Add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS
Add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS for host controllers which do not
support 64-bit addressing.
Ported from Linux kernel commit
6554400d6f66 ("scsi: ufs: core: Add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS")
with ufs_scsi_buffer_aligned() based on U-Boot generic bounce buffer.
Signed-off-by: Marek Vasut <marek.vasut+renesas@mailbox.org>
Reviewed-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>
Tested-by: Bhupesh Sharma <bhupesh.sharma@linaro.org>
Diffstat (limited to 'drivers/ufs/ufs.c')
-rw-r--r-- | drivers/ufs/ufs.c | 26 |
1 files changed, 26 insertions, 0 deletions
diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c index 3bf1a95..da0550d 100644 --- a/drivers/ufs/ufs.c +++ b/drivers/ufs/ufs.c @@ -8,6 +8,7 @@ * Copyright (C) 2019 Texas Instruments Incorporated - http://www.ti.com */ +#include <bouncebuf.h> #include <charset.h> #include <common.h> #include <dm.h> @@ -1889,6 +1890,8 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops) /* Read capabilties registers */ hba->capabilities = ufshcd_readl(hba, REG_CONTROLLER_CAPABILITIES); + if (hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS) + hba->capabilities &= ~MASK_64_ADDRESSING_SUPPORT; /* Get UFS version supported by the controller */ hba->version = ufshcd_get_ufs_version(hba); @@ -1942,8 +1945,31 @@ int ufs_scsi_bind(struct udevice *ufs_dev, struct udevice **scsi_devp) return ret; } +#if IS_ENABLED(CONFIG_BOUNCE_BUFFER) +static int ufs_scsi_buffer_aligned(struct udevice *scsi_dev, struct bounce_buffer *state) +{ +#ifdef CONFIG_PHYS_64BIT + struct ufs_hba *hba = dev_get_uclass_priv(scsi_dev->parent); + uintptr_t ubuf = (uintptr_t)state->user_buffer; + size_t len = state->len_aligned; + + /* Check if below 32bit boundary */ + if ((hba->quirks & UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS) && + ((ubuf >> 32) || (ubuf + len) >> 32)) { + dev_dbg(scsi_dev, "Buffer above 32bit boundary %lx-%lx\n", + ubuf, ubuf + len); + return 0; + } +#endif + return 1; +} +#endif /* CONFIG_BOUNCE_BUFFER */ + static struct scsi_ops ufs_ops = { .exec = ufs_scsi_exec, +#if IS_ENABLED(CONFIG_BOUNCE_BUFFER) + .buffer_aligned = ufs_scsi_buffer_aligned, +#endif /* CONFIG_BOUNCE_BUFFER */ }; int ufs_probe_dev(int index) |