mmc: dw_mmc: Allow lower TMOUT value than maximum
The TMOUT register is always set with a full value for every transfer, which (with a 200MHz clock) will give a full DRTO of ~84 milliseconds. This is normally good enough to complete the request, but setting a full value makes it impossible to test shorter timeouts, when for example testing data read times on different SD cards. Add a function to set any value smaller than the maximum of 0xFFFFFF. Signed-off-by: Mårten Lindahl <marten.lindahl@axis.com> Reviewed-by: Douglas Anderson <dianders@chromium.org> Reviewed-by: Jaehoon Chung <jh80.chung@samsung.com> Link: https://lore.kernel.org/r/20211119155337.14341-1-marten.lindahl@axis.com Signed-off-by: Ulf Hansson <ulf.hansson@linaro.org>
This commit is contained in:
		
							parent
							
								
									76bfc7ccc2
								
							
						
					
					
						commit
						6a8c2018e8
					
				| @ -1284,6 +1284,33 @@ static void dw_mci_setup_bus(struct dw_mci_slot *slot, bool force_clkinit) | ||||
| 	mci_writel(host, CTYPE, (slot->ctype << slot->id)); | ||||
| } | ||||
| 
 | ||||
| static void dw_mci_set_data_timeout(struct dw_mci *host, | ||||
| 				    unsigned int timeout_ns) | ||||
| { | ||||
| 	u32 clk_div, tmout; | ||||
| 	u64 tmp; | ||||
| 
 | ||||
| 	clk_div = (mci_readl(host, CLKDIV) & 0xFF) * 2; | ||||
| 	if (clk_div == 0) | ||||
| 		clk_div = 1; | ||||
| 
 | ||||
| 	tmp = DIV_ROUND_UP_ULL((u64)timeout_ns * host->bus_hz, NSEC_PER_SEC); | ||||
| 	tmp = DIV_ROUND_UP_ULL(tmp, clk_div); | ||||
| 
 | ||||
| 	/* TMOUT[7:0] (RESPONSE_TIMEOUT) */ | ||||
| 	tmout = 0xFF; /* Set maximum */ | ||||
| 
 | ||||
| 	/* TMOUT[31:8] (DATA_TIMEOUT) */ | ||||
| 	if (!tmp || tmp > 0xFFFFFF) | ||||
| 		tmout |= (0xFFFFFF << 8); | ||||
| 	else | ||||
| 		tmout |= (tmp & 0xFFFFFF) << 8; | ||||
| 
 | ||||
| 	mci_writel(host, TMOUT, tmout); | ||||
| 	dev_dbg(host->dev, "timeout_ns: %u => TMOUT[31:8]: 0x%#08x", | ||||
| 		timeout_ns, tmout >> 8); | ||||
| } | ||||
| 
 | ||||
| static void __dw_mci_start_request(struct dw_mci *host, | ||||
| 				   struct dw_mci_slot *slot, | ||||
| 				   struct mmc_command *cmd) | ||||
| @ -1304,7 +1331,7 @@ static void __dw_mci_start_request(struct dw_mci *host, | ||||
| 
 | ||||
| 	data = cmd->data; | ||||
| 	if (data) { | ||||
| 		mci_writel(host, TMOUT, 0xFFFFFFFF); | ||||
| 		dw_mci_set_data_timeout(host, data->timeout_ns); | ||||
| 		mci_writel(host, BYTCNT, data->blksz*data->blocks); | ||||
| 		mci_writel(host, BLKSIZ, data->blksz); | ||||
| 	} | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user