From 86bd0c4a2a5dc4265884648cb92c681646509692 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 12 Jan 2023 15:42:13 -0800 Subject: [PATCH 1/3] scsi: ufs: exynos: Fix DMA alignment for PAGE_SIZE != 4096 The Exynos UFS controller only supports scatter/gather list elements that are aligned on a 4 KiB boundary. Fix DMA alignment in case PAGE_SIZE != 4096. Rename UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE into UFSHCD_QUIRK_4KB_DMA_ALIGNMENT. Cc: Kiwoong Kim Fixes: 2b2bfc8aa519 ("scsi: ufs: Introduce a quirk to allow only page-aligned sg entries") Signed-off-by: Bart Van Assche Reviewed-by: Alim Akhtar Tested-by: Alim Akhtar Signed-off-by: Martin K. Petersen --- drivers/ufs/core/ufshcd.c | 4 ++-- drivers/ufs/host/ufs-exynos.c | 2 +- include/ufs/ufshcd.h | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index 064a6d8605c1..e626810a9abb 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -5107,8 +5107,8 @@ static int ufshcd_slave_configure(struct scsi_device *sdev) ufshcd_hpb_configure(hba, sdev); blk_queue_update_dma_pad(q, PRDT_DATA_BYTE_COUNT_PAD - 1); - if (hba->quirks & UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE) - blk_queue_update_dma_alignment(q, PAGE_SIZE - 1); + if (hba->quirks & UFSHCD_QUIRK_4KB_DMA_ALIGNMENT) + blk_queue_update_dma_alignment(q, 4096 - 1); /* * Block runtime-pm until all consumers are added. * Refer ufshcd_setup_links(). diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index c3628a8645a5..3cdac89a28b8 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -1673,7 +1673,7 @@ static const struct exynos_ufs_drv_data exynos_ufs_drvs = { UFSHCD_QUIRK_BROKEN_OCS_FATAL_ERROR | UFSHCI_QUIRK_SKIP_MANUAL_WB_FLUSH_CTRL | UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING | - UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE, + UFSHCD_QUIRK_4KB_DMA_ALIGNMENT, .opts = EXYNOS_UFS_OPT_HAS_APB_CLK_CTRL | EXYNOS_UFS_OPT_BROKEN_AUTO_CLK_CTRL | EXYNOS_UFS_OPT_BROKEN_RX_SEL_IDX | diff --git a/include/ufs/ufshcd.h b/include/ufs/ufshcd.h index 1779238d8a56..57a5af27522a 100644 --- a/include/ufs/ufshcd.h +++ b/include/ufs/ufshcd.h @@ -583,9 +583,9 @@ enum ufshcd_quirks { UFSHCD_QUIRK_SKIP_DEF_UNIPRO_TIMEOUT_SETTING = 1 << 13, /* - * This quirk allows only sg entries aligned with page size. + * Align DMA SG entries on a 4 KiB boundary. */ - UFSHCD_QUIRK_ALIGN_SG_WITH_PAGE_SIZE = 1 << 14, + UFSHCD_QUIRK_4KB_DMA_ALIGNMENT = 1 << 14, /* * This quirk needs to be enabled if the host controller does not From 9a80bc5debf74b09f3a8bbc02cfba8d04e2048d0 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 12 Jan 2023 15:42:14 -0800 Subject: [PATCH 2/3] scsi: ufs: exynos: Fix the maximum segment size Prepare for enabling DMA clustering and also for supporting PAGE_SIZE != 4096 by declaring explicitly that the maximum segment size is 4096 bytes for Exynos UFS host controllers. Add this code in exynos_ufs_hce_enable_notify() such that it happens after scsi_host_alloc() and before __scsi_init_queue() is called by the LUN scanning code. Cc: Alim Akhtar Cc: Kiwoong Kim Signed-off-by: Bart Van Assche Reviewed-by: Alim Akhtar Tested-by: Alim Akhtar Signed-off-by: Martin K. Petersen --- drivers/ufs/host/ufs-exynos.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/drivers/ufs/host/ufs-exynos.c b/drivers/ufs/host/ufs-exynos.c index 3cdac89a28b8..7c985fc38db1 100644 --- a/drivers/ufs/host/ufs-exynos.c +++ b/drivers/ufs/host/ufs-exynos.c @@ -1300,6 +1300,14 @@ static int exynos_ufs_hce_enable_notify(struct ufs_hba *hba, switch (status) { case PRE_CHANGE: + /* + * The maximum segment size must be set after scsi_host_alloc() + * has been called and before LUN scanning starts + * (ufshcd_async_scan()). Note: this callback may also be called + * from other functions than ufshcd_init(). + */ + hba->host->max_segment_size = 4096; + if (ufs->drv_data->pre_hce_enable) { ret = ufs->drv_data->pre_hce_enable(ufs); if (ret) From 13f87983fb91454e4a534bb41b5b2b43afe97798 Mon Sep 17 00:00:00 2001 From: Bart Van Assche Date: Thu, 12 Jan 2023 15:42:15 -0800 Subject: [PATCH 3/3] scsi: ufs: core: Enable DMA clustering All UFS host controllers support DMA clustering. Hence enable DMA clustering. Notes: - The max_segment_size parameter implements the 256 KiB limit for the PRDT. The dma_boundary parameter represents a boundary that must not be crossed by DMA scatter/gather lists. I'm not aware of any restrictions on DMA scatter/gather lists in the UFSHCI specification other than the 256 KiB limit for the PRDT and the 32-bit address restriction for controllers that only support 32-bits DMA. The latter restriction is already handled by ufshcd_set_dma_mask(). - Without patch "scsi: ufs: exynos: Fix the maximum segment size", this patch breaks support for the Exynos controller. The history of the dma_boundary parameter in the UFS driver is as follows: * The initial UFS driver did not set the dma_boundary parameter. * Commit 4dd4130a722f ("scsi: make sure all drivers set the use_clustering flag") set the .use_clustering flag. * Commit 4af14d113bcf ("scsi: remove the use_clustering flag") removed the use_clustering flag and set the dma_boundary parameter instead. Cc: Avri Altman Cc: Alim Akhtar Cc: Kiwoong Kim Signed-off-by: Bart Van Assche Acked-by: Adrian Hunter Reviewed-by: Alim Akhtar Signed-off-by: Martin K. Petersen --- drivers/ufs/core/ufshcd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/drivers/ufs/core/ufshcd.c b/drivers/ufs/core/ufshcd.c index e626810a9abb..89a78a0f794c 100644 --- a/drivers/ufs/core/ufshcd.c +++ b/drivers/ufs/core/ufshcd.c @@ -8724,7 +8724,6 @@ static struct scsi_host_template ufshcd_driver_template = { .max_host_blocked = 1, .track_queue_depth = 1, .sdev_groups = ufshcd_driver_groups, - .dma_boundary = PAGE_SIZE - 1, .rpm_autosuspend_delay = RPM_AUTOSUSPEND_DELAY_MS, };