aboutsummaryrefslogtreecommitdiff
path: root/drivers/ufs
diff options
context:
space:
mode:
authorMarek Vasut <marek.vasut+renesas@mailbox.org>2023-08-16 17:05:50 +0200
committerTom Rini <trini@konsulko.com>2023-08-24 13:47:43 -0400
commit91913a1aa2ffeb7278d7d4e4bc51565bb38cebeb (patch)
treec18fdc49ce578412123db9c80e8401a651c4ab86 /drivers/ufs
parent5dab730cac673c635a5107a28c0c4288a442f135 (diff)
downloadu-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')
-rw-r--r--drivers/ufs/ufs.c26
-rw-r--r--drivers/ufs/ufs.h6
2 files changed, 32 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)
diff --git a/drivers/ufs/ufs.h b/drivers/ufs/ufs.h
index 5a5c13a..e5ddb6f 100644
--- a/drivers/ufs/ufs.h
+++ b/drivers/ufs/ufs.h
@@ -719,6 +719,12 @@ struct ufs_hba {
*/
#define UFSHCD_QUIRK_BROKEN_LCC BIT(0)
+/*
+ * This quirk needs to be enabled if the host controller has
+ * 64-bit addressing supported capability but it doesn't work.
+ */
+#define UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS BIT(1)
+
/* Virtual memory reference */
struct utp_transfer_cmd_desc *ucdl;
struct utp_transfer_req_desc *utrdl;