Hi Marek,

On 8/14/23 5:22 AM, Marek Vasut wrote:
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+rene...@mailbox.org>
---
Cc: Faiz Abbas <faiz_ab...@ti.com>
---
  drivers/ufs/ufs.c | 26 ++++++++++++++++++++++++++
  drivers/ufs/ufs.h |  6 ++++++
  2 files changed, 32 insertions(+)

diff --git a/drivers/ufs/ufs.c b/drivers/ufs/ufs.c
index 3bf1a95e7f2..da0550d98c6 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 8a38832b05f..070db0dce68 100644
--- a/drivers/ufs/ufs.h
+++ b/drivers/ufs/ufs.h
@@ -719,6 +719,12 @@ struct ufs_hba {
   */
  #define UFSHCD_QUIRK_BROKEN_LCC                               0x1
+/*
+ * 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              0x2
+
        /* Virtual memory reference */
        struct utp_transfer_cmd_desc *ucdl;
        struct utp_transfer_req_desc *utrdl;

For this and the follow-up patch, I think implementing or at least supporting all the quirks currently supported by the Linux UFS driver makes sense as newer controllers do support these quirks.

Accordingly I had sent: https://lists.denx.de/pipermail/u-boot/2023-August/527217.html

So, I would suggest that we pick these two patches and then I can send my patches rebased on the same, but change the .h to support all the possible UFS quirks currently supported in Linux so that subsequent patches can utilize them in u-boot - which I plan to post next.

Thanks,
Bhupesh

Reply via email to