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.

Merge patch series "Prepare for upstreaming Pixel 6 and 7 UFS support"

Bart Van Assche <bvanassche@acm.org> says:

The patches in this series are a first step towards integrating
support in the upstream kernel for the UFS controller in the Pixel 6
and 7.

[mkp: resolve conflict with RPMB series]

Link: https://lore.kernel.org/r/20221208234358.252031-1-bvanassche@acm.org
Signed-off-by: Martin K. Petersen <martin.petersen@oracle.com>

+75 -27
+34 -25
drivers/ufs/core/ufshcd.c
··· 531 531 prdt_length = le16_to_cpu( 532 532 lrbp->utr_descriptor_ptr->prd_table_length); 533 533 if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) 534 - prdt_length /= sizeof(struct ufshcd_sg_entry); 534 + prdt_length /= ufshcd_sg_entry_size(hba); 535 535 536 536 dev_err(hba->dev, 537 537 "UPIU[%d] - PRDT - %d entries phys@0x%llx\n", ··· 540 540 541 541 if (pr_prdt) 542 542 ufshcd_hex_dump("UPIU PRDT: ", lrbp->ucd_prdt_ptr, 543 - sizeof(struct ufshcd_sg_entry) * prdt_length); 543 + ufshcd_sg_entry_size(hba) * prdt_length); 544 544 } 545 545 } 546 546 ··· 1124 1124 return pending; 1125 1125 } 1126 1126 1127 + /* 1128 + * Wait until all pending SCSI commands and TMFs have finished or the timeout 1129 + * has expired. 1130 + * 1131 + * Return: 0 upon success; -EBUSY upon timeout. 1132 + */ 1127 1133 static int ufshcd_wait_for_doorbell_clr(struct ufs_hba *hba, 1128 1134 u64 wait_timeout_us) 1129 1135 { ··· 1163 1157 } 1164 1158 1165 1159 spin_unlock_irqrestore(hba->host->host_lock, flags); 1166 - schedule(); 1160 + io_schedule_timeout(msecs_to_jiffies(20)); 1167 1161 if (ktime_to_us(ktime_sub(ktime_get(), start)) > 1168 1162 wait_timeout_us) { 1169 1163 timeout = true; ··· 1234 1228 return ret; 1235 1229 } 1236 1230 1237 - static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba) 1231 + /* 1232 + * Wait until all pending SCSI commands and TMFs have finished or the timeout 1233 + * has expired. 1234 + * 1235 + * Return: 0 upon success; -EBUSY upon timeout. 1236 + */ 1237 + static int ufshcd_clock_scaling_prepare(struct ufs_hba *hba, u64 timeout_us) 1238 1238 { 1239 - #define DOORBELL_CLR_TOUT_US (1000 * 1000) /* 1 sec */ 1240 1239 int ret = 0; 1241 1240 /* 1242 1241 * make sure that there are no outstanding requests when ··· 1251 1240 down_write(&hba->clk_scaling_lock); 1252 1241 1253 1242 if (!hba->clk_scaling.is_allowed || 1254 - ufshcd_wait_for_doorbell_clr(hba, DOORBELL_CLR_TOUT_US)) { 1243 + ufshcd_wait_for_doorbell_clr(hba, timeout_us)) { 1255 1244 ret = -EBUSY; 1256 1245 up_write(&hba->clk_scaling_lock); 1257 1246 ufshcd_scsi_unblock_requests(hba); ··· 1289 1278 int ret = 0; 1290 1279 bool is_writelock = true; 1291 1280 1292 - ret = ufshcd_clock_scaling_prepare(hba); 1281 + ret = ufshcd_clock_scaling_prepare(hba, 1 * USEC_PER_SEC); 1293 1282 if (ret) 1294 1283 return ret; 1295 1284 ··· 2422 2411 static void ufshcd_sgl_to_prdt(struct ufs_hba *hba, struct ufshcd_lrb *lrbp, int sg_entries, 2423 2412 struct scatterlist *sg_list) 2424 2413 { 2425 - struct ufshcd_sg_entry *prd_table; 2414 + struct ufshcd_sg_entry *prd; 2426 2415 struct scatterlist *sg; 2427 2416 int i; 2428 2417 ··· 2430 2419 2431 2420 if (hba->quirks & UFSHCD_QUIRK_PRDT_BYTE_GRAN) 2432 2421 lrbp->utr_descriptor_ptr->prd_table_length = 2433 - cpu_to_le16((sg_entries * sizeof(struct ufshcd_sg_entry))); 2422 + cpu_to_le16(sg_entries * ufshcd_sg_entry_size(hba)); 2434 2423 else 2435 2424 lrbp->utr_descriptor_ptr->prd_table_length = cpu_to_le16(sg_entries); 2436 2425 2437 - prd_table = lrbp->ucd_prdt_ptr; 2426 + prd = lrbp->ucd_prdt_ptr; 2438 2427 2439 2428 for_each_sg(sg_list, sg, sg_entries, i) { 2440 2429 const unsigned int len = sg_dma_len(sg); ··· 2448 2437 * indicates 4 bytes, '7' indicates 8 bytes, etc." 2449 2438 */ 2450 2439 WARN_ONCE(len > 256 * 1024, "len = %#x\n", len); 2451 - prd_table[i].size = cpu_to_le32(len - 1); 2452 - prd_table[i].addr = cpu_to_le64(sg->dma_address); 2453 - prd_table[i].reserved = 0; 2440 + prd->size = cpu_to_le32(len - 1); 2441 + prd->addr = cpu_to_le64(sg->dma_address); 2442 + prd->reserved = 0; 2443 + prd = (void *)prd + ufshcd_sg_entry_size(hba); 2454 2444 } 2455 2445 } else { 2456 2446 lrbp->utr_descriptor_ptr->prd_table_length = 0; ··· 2758 2746 2759 2747 static void ufshcd_init_lrb(struct ufs_hba *hba, struct ufshcd_lrb *lrb, int i) 2760 2748 { 2761 - struct utp_transfer_cmd_desc *cmd_descp = hba->ucdl_base_addr; 2749 + struct utp_transfer_cmd_desc *cmd_descp = (void *)hba->ucdl_base_addr + 2750 + i * sizeof_utp_transfer_cmd_desc(hba); 2762 2751 struct utp_transfer_req_desc *utrdlp = hba->utrdl_base_addr; 2763 2752 dma_addr_t cmd_desc_element_addr = hba->ucdl_dma_addr + 2764 - i * sizeof(struct utp_transfer_cmd_desc); 2753 + i * sizeof_utp_transfer_cmd_desc(hba); 2765 2754 u16 response_offset = offsetof(struct utp_transfer_cmd_desc, 2766 2755 response_upiu); 2767 2756 u16 prdt_offset = offsetof(struct utp_transfer_cmd_desc, prd_table); ··· 2770 2757 lrb->utr_descriptor_ptr = utrdlp + i; 2771 2758 lrb->utrd_dma_addr = hba->utrdl_dma_addr + 2772 2759 i * sizeof(struct utp_transfer_req_desc); 2773 - lrb->ucd_req_ptr = (struct utp_upiu_req *)(cmd_descp + i); 2760 + lrb->ucd_req_ptr = (struct utp_upiu_req *)cmd_descp->command_upiu; 2774 2761 lrb->ucd_req_dma_addr = cmd_desc_element_addr; 2775 - lrb->ucd_rsp_ptr = (struct utp_upiu_rsp *)cmd_descp[i].response_upiu; 2762 + lrb->ucd_rsp_ptr = (struct utp_upiu_rsp *)cmd_descp->response_upiu; 2776 2763 lrb->ucd_rsp_dma_addr = cmd_desc_element_addr + response_offset; 2777 - lrb->ucd_prdt_ptr = cmd_descp[i].prd_table; 2764 + lrb->ucd_prdt_ptr = (struct ufshcd_sg_entry *)cmd_descp->prd_table; 2778 2765 lrb->ucd_prdt_dma_addr = cmd_desc_element_addr + prdt_offset; 2779 2766 } 2780 2767 ··· 3689 3676 size_t utmrdl_size, utrdl_size, ucdl_size; 3690 3677 3691 3678 /* Allocate memory for UTP command descriptors */ 3692 - ucdl_size = (sizeof(struct utp_transfer_cmd_desc) * hba->nutrs); 3679 + ucdl_size = sizeof_utp_transfer_cmd_desc(hba) * hba->nutrs; 3693 3680 hba->ucdl_base_addr = dmam_alloc_coherent(hba->dev, 3694 3681 ucdl_size, 3695 3682 &hba->ucdl_dma_addr, ··· 3783 3770 prdt_offset = 3784 3771 offsetof(struct utp_transfer_cmd_desc, prd_table); 3785 3772 3786 - cmd_desc_size = sizeof(struct utp_transfer_cmd_desc); 3773 + cmd_desc_size = sizeof_utp_transfer_cmd_desc(hba); 3787 3774 cmd_desc_dma_addr = hba->ucdl_dma_addr; 3788 3775 3789 3776 for (i = 0; i < hba->nutrs; i++) { ··· 9779 9766 hba->dev = dev; 9780 9767 hba->dev_ref_clk_freq = REF_CLK_FREQ_INVAL; 9781 9768 hba->nop_out_timeout = NOP_OUT_TIMEOUT; 9769 + ufshcd_set_sg_entry_size(hba, sizeof(struct ufshcd_sg_entry)); 9782 9770 INIT_LIST_HEAD(&hba->clk_list_head); 9783 9771 spin_lock_init(&hba->outstanding_lock); 9784 9772 ··· 10158 10144 static int __init ufshcd_core_init(void) 10159 10145 { 10160 10146 int ret; 10161 - 10162 - /* Verify that there are no gaps in struct utp_transfer_cmd_desc. */ 10163 - static_assert(sizeof(struct utp_transfer_cmd_desc) == 10164 - 2 * ALIGNED_UPIU_SIZE + 10165 - SG_ALL * sizeof(struct ufshcd_sg_entry)); 10166 10147 10167 10148 ufs_debugfs_init(); 10168 10149
+4
drivers/ufs/host/Kconfig
··· 124 124 125 125 Select this if you have UFS host controller on Samsung Exynos SoC. 126 126 If unsure, say N. 127 + 128 + config SCSI_UFS_VARIABLE_SG_ENTRY_SIZE 129 + bool 130 + default y if SCSI_UFS_EXYNOS && SCSI_UFS_CRYPTO
+30
include/ufs/ufshcd.h
··· 755 755 * @vops: pointer to variant specific operations 756 756 * @vps: pointer to variant specific parameters 757 757 * @priv: pointer to variant specific private data 758 + * @sg_entry_size: size of struct ufshcd_sg_entry (may include variant fields) 758 759 * @irq: Irq number of the controller 759 760 * @is_irq_enabled: whether or not the UFS controller interrupt is enabled. 760 761 * @dev_ref_clk_freq: reference clock frequency ··· 879 878 const struct ufs_hba_variant_ops *vops; 880 879 struct ufs_hba_variant_params *vps; 881 880 void *priv; 881 + #ifdef CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE 882 + size_t sg_entry_size; 883 + #endif 882 884 unsigned int irq; 883 885 bool is_irq_enabled; 884 886 enum ufs_ref_clk_freq dev_ref_clk_freq; ··· 984 980 u32 luns_avail; 985 981 bool complete_put; 986 982 }; 983 + 984 + #ifdef CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE 985 + static inline size_t ufshcd_sg_entry_size(const struct ufs_hba *hba) 986 + { 987 + return hba->sg_entry_size; 988 + } 989 + 990 + static inline void ufshcd_set_sg_entry_size(struct ufs_hba *hba, size_t sg_entry_size) 991 + { 992 + WARN_ON_ONCE(sg_entry_size < sizeof(struct ufshcd_sg_entry)); 993 + hba->sg_entry_size = sg_entry_size; 994 + } 995 + #else 996 + static inline size_t ufshcd_sg_entry_size(const struct ufs_hba *hba) 997 + { 998 + return sizeof(struct ufshcd_sg_entry); 999 + } 1000 + 1001 + #define ufshcd_set_sg_entry_size(hba, sg_entry_size) \ 1002 + ({ (void)(hba); BUILD_BUG_ON(sg_entry_size != sizeof(struct ufshcd_sg_entry)); }) 1003 + #endif 1004 + 1005 + static inline size_t sizeof_utp_transfer_cmd_desc(const struct ufs_hba *hba) 1006 + { 1007 + return sizeof(struct utp_transfer_cmd_desc) + SG_ALL * ufshcd_sg_entry_size(hba); 1008 + } 987 1009 988 1010 /* Returns true if clocks can be gated. Otherwise false */ 989 1011 static inline bool ufshcd_is_clkgating_allowed(struct ufs_hba *hba)
+7 -2
include/ufs/ufshci.h
··· 423 423 __le64 addr; 424 424 __le32 reserved; 425 425 __le32 size; 426 + /* 427 + * followed by variant-specific fields if 428 + * CONFIG_SCSI_UFS_VARIABLE_SG_ENTRY_SIZE has been defined. 429 + */ 426 430 }; 427 431 428 432 /** 429 433 * struct utp_transfer_cmd_desc - UTP Command Descriptor (UCD) 430 434 * @command_upiu: Command UPIU Frame address 431 435 * @response_upiu: Response UPIU Frame address 432 - * @prd_table: Physical Region Descriptor 436 + * @prd_table: Physical Region Descriptor: an array of SG_ALL struct 437 + * ufshcd_sg_entry's. Variant-specific fields may be present after each. 433 438 */ 434 439 struct utp_transfer_cmd_desc { 435 440 u8 command_upiu[ALIGNED_UPIU_SIZE]; 436 441 u8 response_upiu[ALIGNED_UPIU_SIZE]; 437 - struct ufshcd_sg_entry prd_table[SG_ALL]; 442 + u8 prd_table[]; 438 443 }; 439 444 440 445 /**