mirror of
				https://github.com/smaeul/u-boot.git
				synced 2025-11-04 05:50:17 +00:00 
			
		
		
		
	ufs: fix dcache flush and invalidate range calculation
The current calculation will omit doing a flush/invalidate on the last cacheline if the base address is not aligned with DMA_MINALIGN. This causes commands failures and write corruptions on Qualcomm platforms. Reviewed-by: Neha Malcom Francis <n-francis@ti.com> Tested-by: Venkatesh Yadav Abbarapu <venkatesh.abbarapu@amd.com> Tested-by: Julius Lehmann <lehmanju@devpi.de> Link: https://lore.kernel.org/r/20240930-topic-ufs-enhancements-v3-2-58234f84ab89@linaro.org Signed-off-by: Neil Armstrong <neil.armstrong@linaro.org>
This commit is contained in:
		
							parent
							
								
									9c223d8d8b
								
							
						
					
					
						commit
						c64d22b57d
					
				@ -703,11 +703,11 @@ static inline u8 ufshcd_get_upmcrs(struct ufs_hba *hba)
 | 
			
		||||
 */
 | 
			
		||||
static void ufshcd_cache_flush_and_invalidate(void *addr, unsigned long size)
 | 
			
		||||
{
 | 
			
		||||
	uintptr_t aaddr = (uintptr_t)addr & ~(ARCH_DMA_MINALIGN - 1);
 | 
			
		||||
	unsigned long asize = ALIGN(size, ARCH_DMA_MINALIGN);
 | 
			
		||||
	uintptr_t start_addr = (uintptr_t)addr & ~(ARCH_DMA_MINALIGN - 1);
 | 
			
		||||
	uintptr_t end_addr = ALIGN((uintptr_t)addr + size, ARCH_DMA_MINALIGN);
 | 
			
		||||
 | 
			
		||||
	flush_dcache_range(aaddr, aaddr + asize);
 | 
			
		||||
	invalidate_dcache_range(aaddr, aaddr + asize);
 | 
			
		||||
	flush_dcache_range(start_addr, end_addr);
 | 
			
		||||
	invalidate_dcache_range(start_addr, end_addr);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
/**
 | 
			
		||||
@ -1466,13 +1466,13 @@ static void prepare_prdt_table(struct ufs_hba *hba, struct scsi_cmd *pccb)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (pccb->dma_dir == DMA_TO_DEVICE) {	/* Write to device */
 | 
			
		||||
		flush_dcache_range(aaddr, aaddr +
 | 
			
		||||
				   ALIGN(datalen, ARCH_DMA_MINALIGN));
 | 
			
		||||
		flush_dcache_range(aaddr,
 | 
			
		||||
				   ALIGN((uintptr_t)pccb->pdata + datalen, ARCH_DMA_MINALIGN));
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	/* In any case, invalidate cache to avoid stale data in it. */
 | 
			
		||||
	invalidate_dcache_range(aaddr, aaddr +
 | 
			
		||||
				ALIGN(datalen, ARCH_DMA_MINALIGN));
 | 
			
		||||
	invalidate_dcache_range(aaddr,
 | 
			
		||||
				ALIGN((uintptr_t)pccb->pdata + datalen, ARCH_DMA_MINALIGN));
 | 
			
		||||
 | 
			
		||||
	table_length = DIV_ROUND_UP(pccb->datalen, MAX_PRDT_ENTRY);
 | 
			
		||||
	buf = pccb->pdata;
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user