Some UFS controllers can only directly access buffers in system SDRAM and not in other memory (such as various SRAM regions used for low power states).
To enable block reads and writes from UFS to such non-SDRAM addresses, add a quirk forcing the UFS core to use a bounce buffer whenever the requested user buffer falls outside the system RAM range. Signed-off-by: Alexey Charkov <[email protected]> --- drivers/ufs/ufs-uclass.c | 13 ++++++++++--- drivers/ufs/ufs.h | 7 +++++++ 2 files changed, 17 insertions(+), 3 deletions(-) diff --git a/drivers/ufs/ufs-uclass.c b/drivers/ufs/ufs-uclass.c index 3c8e4299259c..8b0e2f5305d6 100644 --- a/drivers/ufs/ufs-uclass.c +++ b/drivers/ufs/ufs-uclass.c @@ -2244,19 +2244,26 @@ int ufshcd_probe(struct udevice *ufs_dev, struct ufs_hba_ops *hba_ops) #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) && + if (IS_ENABLED(CONFIG_PHYS_64BIT) && + (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 + + if ((hba->quirks && UFSHCD_QUIRK_DMA_SDRAM_ONLY) && + (ubuf < gd->ram_base || (ubuf + len) > gd->ram_top)) { + dev_dbg(scsi_dev, "Buffer outside SDRAM %lx-%lx\n", + ubuf, ubuf + len); + return 0; + }; + return 1; } #endif /* CONFIG_BOUNCE_BUFFER */ diff --git a/drivers/ufs/ufs.h b/drivers/ufs/ufs.h index bc839a437045..f860c7143bf7 100644 --- a/drivers/ufs/ufs.h +++ b/drivers/ufs/ufs.h @@ -691,6 +691,13 @@ enum ufshcd_quirks { * single doorbell mode. */ UFSHCD_QUIRK_BROKEN_LSDBS_CAP = 1 << 25, + + /* + * This quirk needs to be enabled if the host controller can only + * access SDRAM addresses but not some other memory type needed for + * U-boot loading or operation + */ + UFSHCD_QUIRK_DMA_SDRAM_ONLY = 1 << 26, }; struct ufs_hba { -- 2.51.2

