Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

scsi: ufs: qcom: Enable UFS Shared ICE Feature

By default, the UFS controller allocates a fixed number of RX and TX
engines statically. Consequently, when UFS reads are in progress, the TX
ICE engines remain idle, and vice versa. This leads to inefficient
utilization of RX and TX engines.

To address this limitation, enable the UFS shared ICE feature for Qualcomm
UFS V5.0 and above. This feature utilizes a pool of crypto cores for both
TX streams (UFS Write – Encryption) and RX streams (UFS Read –
Decryption). With this approach, crypto cores are dynamically allocated to
either the RX or TX stream as needed.

Reviewed-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Co-developed-by: Naveen Kumar Goud Arepalli <quic_narepall@quicinc.com>
Signed-off-by: Naveen Kumar Goud Arepalli <quic_narepall@quicinc.com>
Co-developed-by: Nitin Rawat <quic_nitirawa@quicinc.com>
Signed-off-by: Nitin Rawat <quic_nitirawa@quicinc.com>
Signed-off-by: Ram Kumar Dwivedi <quic_rdwivedi@quicinc.com>
Link: https://lore.kernel.org/r/20250203112739.11425-1-quic_rdwivedi@quicinc.com
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

authored by

Ram Kumar Dwivedi and committed by
Martin K. Petersen
640a6af5 34a84c41

+75 -1
+37
drivers/ufs/host/ufs-qcom.c
··· 15 15 #include <linux/platform_device.h> 16 16 #include <linux/reset-controller.h> 17 17 #include <linux/time.h> 18 + #include <linux/unaligned.h> 18 19 19 20 #include <soc/qcom/ice.h> 20 21 ··· 106 105 } 107 106 108 107 #ifdef CONFIG_SCSI_UFS_CRYPTO 108 + /** 109 + * ufs_qcom_config_ice_allocator() - ICE core allocator configuration 110 + * 111 + * @host: pointer to qcom specific variant structure. 112 + */ 113 + static void ufs_qcom_config_ice_allocator(struct ufs_qcom_host *host) 114 + { 115 + struct ufs_hba *hba = host->hba; 116 + static const uint8_t val[4] = { NUM_RX_R1W0, NUM_TX_R0W1, NUM_RX_R1W1, NUM_TX_R1W1 }; 117 + u32 config; 118 + 119 + if (!(host->caps & UFS_QCOM_CAP_ICE_CONFIG) || 120 + !(host->hba->caps & UFSHCD_CAP_CRYPTO)) 121 + return; 122 + 123 + config = get_unaligned_le32(val); 124 + 125 + ufshcd_writel(hba, ICE_ALLOCATOR_TYPE, REG_UFS_MEM_ICE_CONFIG); 126 + ufshcd_writel(hba, config, REG_UFS_MEM_ICE_NUM_CORE); 127 + } 109 128 110 129 static inline void ufs_qcom_ice_enable(struct ufs_qcom_host *host) 111 130 { ··· 269 248 { 270 249 return 0; 271 250 } 251 + 252 + static void ufs_qcom_config_ice_allocator(struct ufs_qcom_host *host) 253 + { 254 + } 255 + 272 256 #endif 273 257 274 258 static void ufs_qcom_disable_lane_clks(struct ufs_qcom_host *host) ··· 522 496 err = ufs_qcom_check_hibern8(hba); 523 497 ufs_qcom_enable_hw_clk_gating(hba); 524 498 ufs_qcom_ice_enable(host); 499 + ufs_qcom_config_ice_allocator(host); 525 500 break; 526 501 default: 527 502 dev_err(hba->dev, "%s: invalid status %d\n", __func__, status); ··· 1016 989 host_params->hs_tx_gear = host_params->hs_rx_gear = ufs_qcom_get_hs_gear(hba); 1017 990 } 1018 991 992 + static void ufs_qcom_set_host_caps(struct ufs_hba *hba) 993 + { 994 + struct ufs_qcom_host *host = ufshcd_get_variant(hba); 995 + 996 + if (host->hw_ver.major >= 0x5) 997 + host->caps |= UFS_QCOM_CAP_ICE_CONFIG; 998 + } 999 + 1019 1000 static void ufs_qcom_set_caps(struct ufs_hba *hba) 1020 1001 { 1021 1002 hba->caps |= UFSHCD_CAP_CLK_GATING | UFSHCD_CAP_HIBERN8_WITH_CLK_GATING; ··· 1032 997 hba->caps |= UFSHCD_CAP_WB_EN; 1033 998 hba->caps |= UFSHCD_CAP_AGGR_POWER_COLLAPSE; 1034 999 hba->caps |= UFSHCD_CAP_RPM_AUTOSUSPEND; 1000 + 1001 + ufs_qcom_set_host_caps(hba); 1035 1002 } 1036 1003 1037 1004 /**
+38 -1
drivers/ufs/host/ufs-qcom.h
··· 50 50 */ 51 51 UFS_AH8_CFG = 0xFC, 52 52 53 + REG_UFS_MEM_ICE_CONFIG = 0x260C, 54 + REG_UFS_MEM_ICE_NUM_CORE = 0x2664, 55 + 53 56 REG_UFS_CFG3 = 0x271C, 54 57 55 58 REG_UFS_DEBUG_SPARE_CFG = 0x284C, ··· 113 110 /* bit definition for UFS_UFS_TEST_BUS_CTRL_n */ 114 111 #define TEST_BUS_SUB_SEL_MASK GENMASK(4, 0) /* All XXX_SEL fields are 5 bits wide */ 115 112 113 + /* bit definition for UFS Shared ICE config */ 114 + #define UFS_QCOM_CAP_ICE_CONFIG BIT(0) 115 + 116 116 #define REG_UFS_CFG2_CGC_EN_ALL (UAWM_HW_CGC_EN | UARM_HW_CGC_EN |\ 117 117 TXUC_HW_CGC_EN | RXUC_HW_CGC_EN |\ 118 118 DFC_HW_CGC_EN | TRLUT_HW_CGC_EN |\ ··· 140 134 #define UNIPRO_CORE_CLK_FREQ_300_MHZ 300 141 135 #define UNIPRO_CORE_CLK_FREQ_201_5_MHZ 202 142 136 #define UNIPRO_CORE_CLK_FREQ_403_MHZ 403 137 + 138 + /* ICE allocator type to share AES engines among TX stream and RX stream */ 139 + #define ICE_ALLOCATOR_TYPE 2 140 + 141 + /* 142 + * Number of cores allocated for RX stream when Read data block received and 143 + * Write data block is not in progress 144 + */ 145 + #define NUM_RX_R1W0 28 146 + 147 + /* 148 + * Number of cores allocated for TX stream when Device asked to send write 149 + * data block and Read data block is not in progress 150 + */ 151 + #define NUM_TX_R0W1 28 152 + 153 + /* 154 + * Number of cores allocated for RX stream when Read data block received and 155 + * Write data block is in progress 156 + * OR 157 + * Device asked to send write data block and Read data block is in progress 158 + */ 159 + #define NUM_RX_R1W1 15 160 + 161 + /* 162 + * Number of cores allocated for TX stream (UFS write) when Read data block 163 + * received and Write data block is in progress 164 + * OR 165 + * Device asked to send write data block and Read data block is in progress 166 + */ 167 + #define NUM_TX_R1W1 13 143 168 144 169 static inline void 145 170 ufs_qcom_get_controller_revision(struct ufs_hba *hba, ··· 233 196 #ifdef CONFIG_SCSI_UFS_CRYPTO 234 197 struct qcom_ice *ice; 235 198 #endif 236 - 199 + u32 caps; 237 200 void __iomem *dev_ref_clk_ctrl_mmio; 238 201 bool is_dev_ref_clk_enabled; 239 202 struct ufs_hw_version hw_ver;