]> git.dujemihanovic.xyz Git - u-boot.git/commitdiff
ufs: Add UFSHCD_QUIRK_BROKEN_64BIT_ADDRESS
authorMarek Vasut <marek.vasut+renesas@mailbox.org>
Wed, 16 Aug 2023 15:05:50 +0000 (17:05 +0200)
committerTom Rini <trini@konsulko.com>
Thu, 24 Aug 2023 17:47:43 +0000 (13:47 -0400)
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>
drivers/ufs/ufs.c
drivers/ufs/ufs.h

index 3bf1a95e7f2210e5c18d96e8cae8072277494262..da0550d98c691014377cb43d0b22b83bd8c04d6c 100644 (file)
@@ -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)
index 5a5c13aefdfb270d20c8e24b8aa9e0cc656aa9e6..e5ddb6f64a9a81fe107c713e23efaa3d8b37ff21 100644 (file)
@@ -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;