xref: /OK3568_Linux_fs/u-boot/drivers/mmc/sdhci.c (revision 4882a59341e53eb6f0b4789bf948001014eff981)
1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun  * Copyright 2011, Marvell Semiconductor Inc.
3*4882a593Smuzhiyun  * Lei Wen <leiwen@marvell.com>
4*4882a593Smuzhiyun  *
5*4882a593Smuzhiyun  * SPDX-License-Identifier:	GPL-2.0+
6*4882a593Smuzhiyun  *
7*4882a593Smuzhiyun  * Back ported to the 8xx platform (from the 8260 platform) by
8*4882a593Smuzhiyun  * Murray.Jensen@cmst.csiro.au, 27-Jan-01.
9*4882a593Smuzhiyun  */
10*4882a593Smuzhiyun 
11*4882a593Smuzhiyun #include <common.h>
12*4882a593Smuzhiyun #include <errno.h>
13*4882a593Smuzhiyun #include <malloc.h>
14*4882a593Smuzhiyun #include <mmc.h>
15*4882a593Smuzhiyun #include <sdhci.h>
16*4882a593Smuzhiyun 
17*4882a593Smuzhiyun #if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
18*4882a593Smuzhiyun void *aligned_buffer = (void *)CONFIG_FIXED_SDHCI_ALIGNED_BUFFER;
19*4882a593Smuzhiyun #else
20*4882a593Smuzhiyun void *aligned_buffer;
21*4882a593Smuzhiyun #endif
22*4882a593Smuzhiyun 
sdhci_reset(struct sdhci_host * host,u8 mask)23*4882a593Smuzhiyun static void sdhci_reset(struct sdhci_host *host, u8 mask)
24*4882a593Smuzhiyun {
25*4882a593Smuzhiyun 	unsigned long timeout;
26*4882a593Smuzhiyun 
27*4882a593Smuzhiyun 	/* Wait max 100 ms */
28*4882a593Smuzhiyun 	timeout = 100;
29*4882a593Smuzhiyun 	sdhci_writeb(host, mask, SDHCI_SOFTWARE_RESET);
30*4882a593Smuzhiyun 	while (sdhci_readb(host, SDHCI_SOFTWARE_RESET) & mask) {
31*4882a593Smuzhiyun 		if (timeout == 0) {
32*4882a593Smuzhiyun 			printf("%s: Reset 0x%x never completed.\n",
33*4882a593Smuzhiyun 			       __func__, (int)mask);
34*4882a593Smuzhiyun 			return;
35*4882a593Smuzhiyun 		}
36*4882a593Smuzhiyun 		timeout--;
37*4882a593Smuzhiyun 		udelay(1000);
38*4882a593Smuzhiyun 	}
39*4882a593Smuzhiyun }
40*4882a593Smuzhiyun 
sdhci_cmd_done(struct sdhci_host * host,struct mmc_cmd * cmd)41*4882a593Smuzhiyun static void sdhci_cmd_done(struct sdhci_host *host, struct mmc_cmd *cmd)
42*4882a593Smuzhiyun {
43*4882a593Smuzhiyun 	int i;
44*4882a593Smuzhiyun 	if (cmd->resp_type & MMC_RSP_136) {
45*4882a593Smuzhiyun 		/* CRC is stripped so we need to do some shifting. */
46*4882a593Smuzhiyun 		for (i = 0; i < 4; i++) {
47*4882a593Smuzhiyun 			cmd->response[i] = sdhci_readl(host,
48*4882a593Smuzhiyun 					SDHCI_RESPONSE + (3-i)*4) << 8;
49*4882a593Smuzhiyun 			if (i != 3)
50*4882a593Smuzhiyun 				cmd->response[i] |= sdhci_readb(host,
51*4882a593Smuzhiyun 						SDHCI_RESPONSE + (3-i)*4-1);
52*4882a593Smuzhiyun 		}
53*4882a593Smuzhiyun 	} else {
54*4882a593Smuzhiyun 		cmd->response[0] = sdhci_readl(host, SDHCI_RESPONSE);
55*4882a593Smuzhiyun 	}
56*4882a593Smuzhiyun }
57*4882a593Smuzhiyun 
sdhci_transfer_pio(struct sdhci_host * host,struct mmc_data * data)58*4882a593Smuzhiyun static void sdhci_transfer_pio(struct sdhci_host *host, struct mmc_data *data)
59*4882a593Smuzhiyun {
60*4882a593Smuzhiyun 	int i;
61*4882a593Smuzhiyun 	char *offs;
62*4882a593Smuzhiyun 	for (i = 0; i < data->blocksize; i += 4) {
63*4882a593Smuzhiyun 		offs = data->dest + i;
64*4882a593Smuzhiyun 		if (data->flags == MMC_DATA_READ)
65*4882a593Smuzhiyun 			*(u32 *)offs = sdhci_readl(host, SDHCI_BUFFER);
66*4882a593Smuzhiyun 		else
67*4882a593Smuzhiyun 			sdhci_writel(host, *(u32 *)offs, SDHCI_BUFFER);
68*4882a593Smuzhiyun 	}
69*4882a593Smuzhiyun }
70*4882a593Smuzhiyun 
sdhci_transfer_data(struct sdhci_host * host,struct mmc_data * data,unsigned int start_addr)71*4882a593Smuzhiyun static int sdhci_transfer_data(struct sdhci_host *host, struct mmc_data *data,
72*4882a593Smuzhiyun 				unsigned int start_addr)
73*4882a593Smuzhiyun {
74*4882a593Smuzhiyun 	unsigned int stat, rdy, mask, timeout, block = 0;
75*4882a593Smuzhiyun 	bool transfer_done = false;
76*4882a593Smuzhiyun #ifdef CONFIG_MMC_SDHCI_SDMA
77*4882a593Smuzhiyun 	unsigned char ctrl;
78*4882a593Smuzhiyun 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
79*4882a593Smuzhiyun 	ctrl &= ~SDHCI_CTRL_DMA_MASK;
80*4882a593Smuzhiyun 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
81*4882a593Smuzhiyun #endif
82*4882a593Smuzhiyun 
83*4882a593Smuzhiyun 	timeout = 1000000;
84*4882a593Smuzhiyun 	rdy = SDHCI_INT_SPACE_AVAIL | SDHCI_INT_DATA_AVAIL;
85*4882a593Smuzhiyun 	mask = SDHCI_DATA_AVAILABLE | SDHCI_SPACE_AVAILABLE;
86*4882a593Smuzhiyun 	do {
87*4882a593Smuzhiyun 		stat = sdhci_readl(host, SDHCI_INT_STATUS);
88*4882a593Smuzhiyun 		if (stat & SDHCI_INT_ERROR) {
89*4882a593Smuzhiyun 			printf("%s: Error detected in status(0x%X)!\n",
90*4882a593Smuzhiyun 			       __func__, stat);
91*4882a593Smuzhiyun 			return -EIO;
92*4882a593Smuzhiyun 		}
93*4882a593Smuzhiyun 		if (!transfer_done && (stat & rdy)) {
94*4882a593Smuzhiyun 			if (!(sdhci_readl(host, SDHCI_PRESENT_STATE) & mask))
95*4882a593Smuzhiyun 				continue;
96*4882a593Smuzhiyun 			sdhci_writel(host, rdy, SDHCI_INT_STATUS);
97*4882a593Smuzhiyun 			sdhci_transfer_pio(host, data);
98*4882a593Smuzhiyun 			data->dest += data->blocksize;
99*4882a593Smuzhiyun 			if (++block >= data->blocks) {
100*4882a593Smuzhiyun 				/* Keep looping until the SDHCI_INT_DATA_END is
101*4882a593Smuzhiyun 				 * cleared, even if we finished sending all the
102*4882a593Smuzhiyun 				 * blocks.
103*4882a593Smuzhiyun 				 */
104*4882a593Smuzhiyun 				transfer_done = true;
105*4882a593Smuzhiyun 				continue;
106*4882a593Smuzhiyun 			}
107*4882a593Smuzhiyun 		}
108*4882a593Smuzhiyun #ifdef CONFIG_MMC_SDHCI_SDMA
109*4882a593Smuzhiyun 		if (!transfer_done && (stat & SDHCI_INT_DMA_END)) {
110*4882a593Smuzhiyun 			sdhci_writel(host, SDHCI_INT_DMA_END, SDHCI_INT_STATUS);
111*4882a593Smuzhiyun 			start_addr &= ~(SDHCI_DEFAULT_BOUNDARY_SIZE - 1);
112*4882a593Smuzhiyun 			start_addr += SDHCI_DEFAULT_BOUNDARY_SIZE;
113*4882a593Smuzhiyun 			sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS);
114*4882a593Smuzhiyun 		}
115*4882a593Smuzhiyun #endif
116*4882a593Smuzhiyun 		if (timeout-- > 0)
117*4882a593Smuzhiyun 			udelay(10);
118*4882a593Smuzhiyun 		else {
119*4882a593Smuzhiyun 			printf("%s: Transfer data timeout\n", __func__);
120*4882a593Smuzhiyun 			return -ETIMEDOUT;
121*4882a593Smuzhiyun 		}
122*4882a593Smuzhiyun 	} while (!(stat & SDHCI_INT_DATA_END));
123*4882a593Smuzhiyun 	return 0;
124*4882a593Smuzhiyun }
125*4882a593Smuzhiyun 
126*4882a593Smuzhiyun /*
127*4882a593Smuzhiyun  * No command will be sent by driver if card is busy, so driver must wait
128*4882a593Smuzhiyun  * for card ready state.
129*4882a593Smuzhiyun  * Every time when card is busy after timeout then (last) timeout value will be
130*4882a593Smuzhiyun  * increased twice but only if it doesn't exceed global defined maximum.
131*4882a593Smuzhiyun  * Each function call will use last timeout value.
132*4882a593Smuzhiyun  */
133*4882a593Smuzhiyun #define SDHCI_CMD_MAX_TIMEOUT			3200
134*4882a593Smuzhiyun #define SDHCI_CMD_DEFAULT_TIMEOUT		100
135*4882a593Smuzhiyun #define SDHCI_READ_STATUS_TIMEOUT		1000
136*4882a593Smuzhiyun 
137*4882a593Smuzhiyun #ifdef CONFIG_DM_MMC
sdhci_send_command(struct udevice * dev,struct mmc_cmd * cmd,struct mmc_data * data)138*4882a593Smuzhiyun static int sdhci_send_command(struct udevice *dev, struct mmc_cmd *cmd,
139*4882a593Smuzhiyun 			      struct mmc_data *data)
140*4882a593Smuzhiyun {
141*4882a593Smuzhiyun 	struct mmc *mmc = mmc_get_mmc_dev(dev);
142*4882a593Smuzhiyun 
143*4882a593Smuzhiyun #else
144*4882a593Smuzhiyun static int sdhci_send_command(struct mmc *mmc, struct mmc_cmd *cmd,
145*4882a593Smuzhiyun 			      struct mmc_data *data)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun #endif
148*4882a593Smuzhiyun 	struct sdhci_host *host = mmc->priv;
149*4882a593Smuzhiyun 	unsigned int stat = 0;
150*4882a593Smuzhiyun 	int ret = 0;
151*4882a593Smuzhiyun 	int trans_bytes = 0, is_aligned = 1;
152*4882a593Smuzhiyun 	u32 mask, flags, mode;
153*4882a593Smuzhiyun 	unsigned int time = 0, start_addr = 0;
154*4882a593Smuzhiyun 	int mmc_dev = mmc_get_blk_desc(mmc)->devnum;
155*4882a593Smuzhiyun 	unsigned start = get_timer(0);
156*4882a593Smuzhiyun 
157*4882a593Smuzhiyun 	/* Timeout unit - ms */
158*4882a593Smuzhiyun 	static unsigned int cmd_timeout = SDHCI_CMD_DEFAULT_TIMEOUT;
159*4882a593Smuzhiyun 
160*4882a593Smuzhiyun 	mask = SDHCI_CMD_INHIBIT;
161*4882a593Smuzhiyun 
162*4882a593Smuzhiyun 	if (data)
163*4882a593Smuzhiyun 		mask |= SDHCI_DATA_INHIBIT;
164*4882a593Smuzhiyun 
165*4882a593Smuzhiyun 	/* We shouldn't wait for data inihibit for stop commands, even
166*4882a593Smuzhiyun 	   though they might use busy signaling */
167*4882a593Smuzhiyun 	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
168*4882a593Smuzhiyun 		mask &= ~SDHCI_DATA_INHIBIT;
169*4882a593Smuzhiyun 
170*4882a593Smuzhiyun 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) & mask) {
171*4882a593Smuzhiyun 		if (time >= cmd_timeout) {
172*4882a593Smuzhiyun 			printf("%s: MMC: %d busy ", __func__, mmc_dev);
173*4882a593Smuzhiyun 			if (2 * cmd_timeout <= SDHCI_CMD_MAX_TIMEOUT) {
174*4882a593Smuzhiyun 				cmd_timeout += cmd_timeout;
175*4882a593Smuzhiyun 				printf("timeout increasing to: %u ms.\n",
176*4882a593Smuzhiyun 				       cmd_timeout);
177*4882a593Smuzhiyun 				sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
178*4882a593Smuzhiyun 			} else {
179*4882a593Smuzhiyun 				puts("timeout.\n");
180*4882a593Smuzhiyun 				/* remove timeout return error and try to send command */
181*4882a593Smuzhiyun 				break;
182*4882a593Smuzhiyun 			}
183*4882a593Smuzhiyun 		}
184*4882a593Smuzhiyun 		time++;
185*4882a593Smuzhiyun 		udelay(1000);
186*4882a593Smuzhiyun 	}
187*4882a593Smuzhiyun 
188*4882a593Smuzhiyun 	sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
189*4882a593Smuzhiyun 
190*4882a593Smuzhiyun 	mask = SDHCI_INT_RESPONSE;
191*4882a593Smuzhiyun 	if (!(cmd->resp_type & MMC_RSP_PRESENT))
192*4882a593Smuzhiyun 		flags = SDHCI_CMD_RESP_NONE;
193*4882a593Smuzhiyun 	else if (cmd->resp_type & MMC_RSP_136)
194*4882a593Smuzhiyun 		flags = SDHCI_CMD_RESP_LONG;
195*4882a593Smuzhiyun 	else if (cmd->resp_type & MMC_RSP_BUSY) {
196*4882a593Smuzhiyun 		flags = SDHCI_CMD_RESP_SHORT_BUSY;
197*4882a593Smuzhiyun 		if (data)
198*4882a593Smuzhiyun 			mask |= SDHCI_INT_DATA_END;
199*4882a593Smuzhiyun 	} else
200*4882a593Smuzhiyun 		flags = SDHCI_CMD_RESP_SHORT;
201*4882a593Smuzhiyun 
202*4882a593Smuzhiyun 	if (cmd->resp_type & MMC_RSP_CRC)
203*4882a593Smuzhiyun 		flags |= SDHCI_CMD_CRC;
204*4882a593Smuzhiyun 	if (cmd->resp_type & MMC_RSP_OPCODE)
205*4882a593Smuzhiyun 		flags |= SDHCI_CMD_INDEX;
206*4882a593Smuzhiyun 	if (data)
207*4882a593Smuzhiyun 		flags |= SDHCI_CMD_DATA;
208*4882a593Smuzhiyun 
209*4882a593Smuzhiyun 	if (cmd->cmdidx == MMC_SEND_TUNING_BLOCK ||
210*4882a593Smuzhiyun 	    cmd->cmdidx == MMC_SEND_TUNING_BLOCK_HS200) {
211*4882a593Smuzhiyun 		mask &= ~SDHCI_INT_RESPONSE;
212*4882a593Smuzhiyun 		mask |= SDHCI_INT_DATA_AVAIL;
213*4882a593Smuzhiyun 		flags |= SDHCI_CMD_DATA;
214*4882a593Smuzhiyun 	}
215*4882a593Smuzhiyun 
216*4882a593Smuzhiyun 	/* Set Transfer mode regarding to data flag */
217*4882a593Smuzhiyun 	if (data != 0) {
218*4882a593Smuzhiyun 		sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
219*4882a593Smuzhiyun 		mode = SDHCI_TRNS_BLK_CNT_EN;
220*4882a593Smuzhiyun 		trans_bytes = data->blocks * data->blocksize;
221*4882a593Smuzhiyun 		if (data->blocks > 1)
222*4882a593Smuzhiyun 			mode |= SDHCI_TRNS_MULTI;
223*4882a593Smuzhiyun 
224*4882a593Smuzhiyun 		if (data->flags == MMC_DATA_READ)
225*4882a593Smuzhiyun 			mode |= SDHCI_TRNS_READ;
226*4882a593Smuzhiyun 
227*4882a593Smuzhiyun #ifdef CONFIG_MMC_SDHCI_SDMA
228*4882a593Smuzhiyun 		if (data->flags == MMC_DATA_READ)
229*4882a593Smuzhiyun 			start_addr = (unsigned long)data->dest;
230*4882a593Smuzhiyun 		else
231*4882a593Smuzhiyun 			start_addr = (unsigned long)data->src;
232*4882a593Smuzhiyun 		if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
233*4882a593Smuzhiyun 				(start_addr & 0x7) != 0x0) {
234*4882a593Smuzhiyun 			is_aligned = 0;
235*4882a593Smuzhiyun 			start_addr = (unsigned long)aligned_buffer;
236*4882a593Smuzhiyun 			if (data->flags != MMC_DATA_READ)
237*4882a593Smuzhiyun 				memcpy(aligned_buffer, data->src, trans_bytes);
238*4882a593Smuzhiyun 		}
239*4882a593Smuzhiyun 
240*4882a593Smuzhiyun #if defined(CONFIG_FIXED_SDHCI_ALIGNED_BUFFER)
241*4882a593Smuzhiyun 		/*
242*4882a593Smuzhiyun 		 * Always use this bounce-buffer when
243*4882a593Smuzhiyun 		 * CONFIG_FIXED_SDHCI_ALIGNED_BUFFER is defined
244*4882a593Smuzhiyun 		 */
245*4882a593Smuzhiyun 		is_aligned = 0;
246*4882a593Smuzhiyun 		start_addr = (unsigned long)aligned_buffer;
247*4882a593Smuzhiyun 		if (data->flags != MMC_DATA_READ)
248*4882a593Smuzhiyun 			memcpy(aligned_buffer, data->src, trans_bytes);
249*4882a593Smuzhiyun #endif
250*4882a593Smuzhiyun 
251*4882a593Smuzhiyun 		sdhci_writel(host, start_addr, SDHCI_DMA_ADDRESS);
252*4882a593Smuzhiyun 		mode |= SDHCI_TRNS_DMA;
253*4882a593Smuzhiyun #endif
254*4882a593Smuzhiyun 		sdhci_writew(host, SDHCI_MAKE_BLKSZ(SDHCI_DEFAULT_BOUNDARY_ARG,
255*4882a593Smuzhiyun 				data->blocksize),
256*4882a593Smuzhiyun 				SDHCI_BLOCK_SIZE);
257*4882a593Smuzhiyun 		sdhci_writew(host, data->blocks, SDHCI_BLOCK_COUNT);
258*4882a593Smuzhiyun 		sdhci_writew(host, mode, SDHCI_TRANSFER_MODE);
259*4882a593Smuzhiyun 	} else if (cmd->resp_type & MMC_RSP_BUSY) {
260*4882a593Smuzhiyun 		sdhci_writeb(host, 0xe, SDHCI_TIMEOUT_CONTROL);
261*4882a593Smuzhiyun 	}
262*4882a593Smuzhiyun 
263*4882a593Smuzhiyun 	sdhci_writel(host, cmd->cmdarg, SDHCI_ARGUMENT);
264*4882a593Smuzhiyun #ifdef CONFIG_MMC_SDHCI_SDMA
265*4882a593Smuzhiyun 	if (data != 0) {
266*4882a593Smuzhiyun 		trans_bytes = ALIGN(trans_bytes, CONFIG_SYS_CACHELINE_SIZE);
267*4882a593Smuzhiyun 		flush_cache(start_addr, trans_bytes);
268*4882a593Smuzhiyun 	}
269*4882a593Smuzhiyun #endif
270*4882a593Smuzhiyun 	sdhci_writew(host, SDHCI_MAKE_CMD(cmd->cmdidx, flags), SDHCI_COMMAND);
271*4882a593Smuzhiyun 	start = get_timer(0);
272*4882a593Smuzhiyun 	do {
273*4882a593Smuzhiyun 		stat = sdhci_readl(host, SDHCI_INT_STATUS);
274*4882a593Smuzhiyun 		if (stat & SDHCI_INT_ERROR)
275*4882a593Smuzhiyun 			break;
276*4882a593Smuzhiyun 
277*4882a593Smuzhiyun 		if (get_timer(start) >= SDHCI_READ_STATUS_TIMEOUT) {
278*4882a593Smuzhiyun 			if (host->quirks & SDHCI_QUIRK_BROKEN_R1B) {
279*4882a593Smuzhiyun 				return 0;
280*4882a593Smuzhiyun 			} else {
281*4882a593Smuzhiyun 				printf("%s: Timeout for status update!\n",
282*4882a593Smuzhiyun 				       __func__);
283*4882a593Smuzhiyun 				return -ETIMEDOUT;
284*4882a593Smuzhiyun 			}
285*4882a593Smuzhiyun 		}
286*4882a593Smuzhiyun 	} while ((stat & mask) != mask);
287*4882a593Smuzhiyun 
288*4882a593Smuzhiyun 	if ((stat & (SDHCI_INT_ERROR | mask)) == mask) {
289*4882a593Smuzhiyun 		sdhci_cmd_done(host, cmd);
290*4882a593Smuzhiyun 		sdhci_writel(host, mask, SDHCI_INT_STATUS);
291*4882a593Smuzhiyun 	} else
292*4882a593Smuzhiyun 		ret = -1;
293*4882a593Smuzhiyun 
294*4882a593Smuzhiyun 	if (!ret && data)
295*4882a593Smuzhiyun 		ret = sdhci_transfer_data(host, data, start_addr);
296*4882a593Smuzhiyun 
297*4882a593Smuzhiyun 	if (host->quirks & SDHCI_QUIRK_WAIT_SEND_CMD)
298*4882a593Smuzhiyun 		udelay(1000);
299*4882a593Smuzhiyun 
300*4882a593Smuzhiyun 	stat = sdhci_readl(host, SDHCI_INT_STATUS);
301*4882a593Smuzhiyun 	sdhci_writel(host, SDHCI_INT_ALL_MASK, SDHCI_INT_STATUS);
302*4882a593Smuzhiyun 	if (!ret) {
303*4882a593Smuzhiyun 		if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) &&
304*4882a593Smuzhiyun 				!is_aligned && (data->flags == MMC_DATA_READ))
305*4882a593Smuzhiyun 			memcpy(data->dest, aligned_buffer, trans_bytes);
306*4882a593Smuzhiyun 		return 0;
307*4882a593Smuzhiyun 	}
308*4882a593Smuzhiyun 
309*4882a593Smuzhiyun 	sdhci_reset(host, SDHCI_RESET_CMD);
310*4882a593Smuzhiyun 	sdhci_reset(host, SDHCI_RESET_DATA);
311*4882a593Smuzhiyun 	if (stat & SDHCI_INT_TIMEOUT)
312*4882a593Smuzhiyun 		return -ETIMEDOUT;
313*4882a593Smuzhiyun 	else
314*4882a593Smuzhiyun 		return -ECOMM;
315*4882a593Smuzhiyun }
316*4882a593Smuzhiyun 
317*4882a593Smuzhiyun void sdhci_enable_clk(struct sdhci_host *host, u16 clk)
318*4882a593Smuzhiyun {
319*4882a593Smuzhiyun 	unsigned int timeout;
320*4882a593Smuzhiyun 
321*4882a593Smuzhiyun 	clk |= SDHCI_CLOCK_INT_EN;
322*4882a593Smuzhiyun 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
323*4882a593Smuzhiyun 
324*4882a593Smuzhiyun 	/* Wait max 20 ms */
325*4882a593Smuzhiyun 	timeout = 20;
326*4882a593Smuzhiyun 	while (!((clk = sdhci_readw(host, SDHCI_CLOCK_CONTROL))
327*4882a593Smuzhiyun 		& SDHCI_CLOCK_INT_STABLE)) {
328*4882a593Smuzhiyun 		if (timeout == 0) {
329*4882a593Smuzhiyun 			printf("%s: Internal clock never stabilised.\n",
330*4882a593Smuzhiyun 			       __func__);
331*4882a593Smuzhiyun 			return;
332*4882a593Smuzhiyun 		}
333*4882a593Smuzhiyun 		timeout--;
334*4882a593Smuzhiyun 		udelay(1000);
335*4882a593Smuzhiyun 	}
336*4882a593Smuzhiyun 	clk |= SDHCI_CLOCK_CARD_EN;
337*4882a593Smuzhiyun 	sdhci_writew(host, clk, SDHCI_CLOCK_CONTROL);
338*4882a593Smuzhiyun }
339*4882a593Smuzhiyun 
340*4882a593Smuzhiyun int sdhci_set_clock(struct sdhci_host *host, unsigned int clock)
341*4882a593Smuzhiyun {
342*4882a593Smuzhiyun 	unsigned int div, clk = 0, timeout;
343*4882a593Smuzhiyun 
344*4882a593Smuzhiyun 	/* Wait max 20 ms */
345*4882a593Smuzhiyun 	timeout = 200;
346*4882a593Smuzhiyun 	while (sdhci_readl(host, SDHCI_PRESENT_STATE) &
347*4882a593Smuzhiyun 			   (SDHCI_CMD_INHIBIT | SDHCI_DATA_INHIBIT)) {
348*4882a593Smuzhiyun 		if (timeout == 0) {
349*4882a593Smuzhiyun 			printf("%s: Timeout to wait cmd & data inhibit\n",
350*4882a593Smuzhiyun 			       __func__);
351*4882a593Smuzhiyun 			return -EBUSY;
352*4882a593Smuzhiyun 		}
353*4882a593Smuzhiyun 
354*4882a593Smuzhiyun 		timeout--;
355*4882a593Smuzhiyun 		udelay(100);
356*4882a593Smuzhiyun 	}
357*4882a593Smuzhiyun 	sdhci_writew(host, 0, SDHCI_CLOCK_CONTROL);
358*4882a593Smuzhiyun 
359*4882a593Smuzhiyun 	if (clock == 0)
360*4882a593Smuzhiyun 		return 0;
361*4882a593Smuzhiyun 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
362*4882a593Smuzhiyun 		/*
363*4882a593Smuzhiyun 		 * Check if the Host Controller supports Programmable Clock
364*4882a593Smuzhiyun 		 * Mode.
365*4882a593Smuzhiyun 		 */
366*4882a593Smuzhiyun 		if (host->clk_mul) {
367*4882a593Smuzhiyun 			for (div = 1; div <= 1024; div++) {
368*4882a593Smuzhiyun 				if ((host->max_clk / div) <= clock)
369*4882a593Smuzhiyun 					break;
370*4882a593Smuzhiyun 			}
371*4882a593Smuzhiyun 
372*4882a593Smuzhiyun 			/*
373*4882a593Smuzhiyun 			 * Set Programmable Clock Mode in the Clock
374*4882a593Smuzhiyun 			 * Control register.
375*4882a593Smuzhiyun 			 */
376*4882a593Smuzhiyun 			clk = SDHCI_PROG_CLOCK_MODE;
377*4882a593Smuzhiyun 			div--;
378*4882a593Smuzhiyun 		} else {
379*4882a593Smuzhiyun 			/* Version 3.00 divisors must be a multiple of 2. */
380*4882a593Smuzhiyun 			if (host->max_clk <= clock) {
381*4882a593Smuzhiyun 				div = 1;
382*4882a593Smuzhiyun 			} else {
383*4882a593Smuzhiyun 				for (div = 2;
384*4882a593Smuzhiyun 				     div < SDHCI_MAX_DIV_SPEC_300;
385*4882a593Smuzhiyun 				     div += 2) {
386*4882a593Smuzhiyun 					if ((host->max_clk / div) <= clock)
387*4882a593Smuzhiyun 						break;
388*4882a593Smuzhiyun 				}
389*4882a593Smuzhiyun 			}
390*4882a593Smuzhiyun 			div >>= 1;
391*4882a593Smuzhiyun 		}
392*4882a593Smuzhiyun 	} else {
393*4882a593Smuzhiyun 		/* Version 2.00 divisors must be a power of 2. */
394*4882a593Smuzhiyun 		for (div = 1; div < SDHCI_MAX_DIV_SPEC_200; div *= 2) {
395*4882a593Smuzhiyun 			if ((host->max_clk / div) <= clock)
396*4882a593Smuzhiyun 				break;
397*4882a593Smuzhiyun 		}
398*4882a593Smuzhiyun 		div >>= 1;
399*4882a593Smuzhiyun 	}
400*4882a593Smuzhiyun 	if (host->ops && host->ops->set_clock_ext)
401*4882a593Smuzhiyun 		host->ops->set_clock_ext(host, div);
402*4882a593Smuzhiyun 
403*4882a593Smuzhiyun 	clk |= (div & SDHCI_DIV_MASK) << SDHCI_DIVIDER_SHIFT;
404*4882a593Smuzhiyun 	clk |= ((div & SDHCI_DIV_HI_MASK) >> SDHCI_DIV_MASK_LEN)
405*4882a593Smuzhiyun 		<< SDHCI_DIVIDER_HI_SHIFT;
406*4882a593Smuzhiyun 
407*4882a593Smuzhiyun 	sdhci_enable_clk(host, clk);
408*4882a593Smuzhiyun 
409*4882a593Smuzhiyun 	host->clock = clock;
410*4882a593Smuzhiyun 	return 0;
411*4882a593Smuzhiyun }
412*4882a593Smuzhiyun 
413*4882a593Smuzhiyun static void sdhci_set_power(struct sdhci_host *host, unsigned short power)
414*4882a593Smuzhiyun {
415*4882a593Smuzhiyun 	u8 pwr = 0;
416*4882a593Smuzhiyun 
417*4882a593Smuzhiyun 	if (power != (unsigned short)-1) {
418*4882a593Smuzhiyun 		switch (1 << power) {
419*4882a593Smuzhiyun 		case MMC_VDD_165_195:
420*4882a593Smuzhiyun 			pwr = SDHCI_POWER_180;
421*4882a593Smuzhiyun 			break;
422*4882a593Smuzhiyun 		case MMC_VDD_29_30:
423*4882a593Smuzhiyun 		case MMC_VDD_30_31:
424*4882a593Smuzhiyun 			pwr = SDHCI_POWER_300;
425*4882a593Smuzhiyun 			break;
426*4882a593Smuzhiyun 		case MMC_VDD_32_33:
427*4882a593Smuzhiyun 		case MMC_VDD_33_34:
428*4882a593Smuzhiyun 			pwr = SDHCI_POWER_330;
429*4882a593Smuzhiyun 			break;
430*4882a593Smuzhiyun 		}
431*4882a593Smuzhiyun 	}
432*4882a593Smuzhiyun 
433*4882a593Smuzhiyun 	if (pwr == 0) {
434*4882a593Smuzhiyun 		sdhci_writeb(host, 0, SDHCI_POWER_CONTROL);
435*4882a593Smuzhiyun 		return;
436*4882a593Smuzhiyun 	}
437*4882a593Smuzhiyun 
438*4882a593Smuzhiyun 	pwr |= SDHCI_POWER_ON;
439*4882a593Smuzhiyun 
440*4882a593Smuzhiyun 	sdhci_writeb(host, pwr, SDHCI_POWER_CONTROL);
441*4882a593Smuzhiyun }
442*4882a593Smuzhiyun 
443*4882a593Smuzhiyun static void sdhci_set_uhs_signaling(struct sdhci_host *host)
444*4882a593Smuzhiyun {
445*4882a593Smuzhiyun 	u16 ctrl_2;
446*4882a593Smuzhiyun 	u32 timing = host->mmc->timing;
447*4882a593Smuzhiyun 
448*4882a593Smuzhiyun 	ctrl_2 = sdhci_readw(host, SDHCI_HOST_CONTROL2);
449*4882a593Smuzhiyun 	/* Select Bus Speed Mode for host */
450*4882a593Smuzhiyun 	ctrl_2 &= ~SDHCI_CTRL_UHS_MASK;
451*4882a593Smuzhiyun 
452*4882a593Smuzhiyun 	if ((timing != MMC_TIMING_LEGACY) &&
453*4882a593Smuzhiyun 	    (timing != MMC_TIMING_MMC_HS) &&
454*4882a593Smuzhiyun 	    (timing != MMC_TIMING_SD_HS))
455*4882a593Smuzhiyun 		ctrl_2 |= SDHCI_CTRL_VDD_180;
456*4882a593Smuzhiyun 
457*4882a593Smuzhiyun 	if ((timing == MMC_TIMING_MMC_HS200) ||
458*4882a593Smuzhiyun 	    (timing == MMC_TIMING_UHS_SDR104))
459*4882a593Smuzhiyun 		ctrl_2 |= SDHCI_CTRL_UHS_SDR104 | SDHCI_CTRL_DRV_TYPE_A;
460*4882a593Smuzhiyun 	else if (timing == MMC_TIMING_UHS_SDR12)
461*4882a593Smuzhiyun 		ctrl_2 |= SDHCI_CTRL_UHS_SDR12;
462*4882a593Smuzhiyun 	else if (timing == MMC_TIMING_UHS_SDR25)
463*4882a593Smuzhiyun 		ctrl_2 |= SDHCI_CTRL_UHS_SDR25;
464*4882a593Smuzhiyun 	else if ((timing == MMC_TIMING_UHS_SDR50) ||
465*4882a593Smuzhiyun 		(timing == MMC_TIMING_MMC_HS))
466*4882a593Smuzhiyun 		ctrl_2 |= SDHCI_CTRL_UHS_SDR50;
467*4882a593Smuzhiyun 	else if ((timing == MMC_TIMING_UHS_DDR50) ||
468*4882a593Smuzhiyun 		 (timing == MMC_TIMING_MMC_DDR52))
469*4882a593Smuzhiyun 		ctrl_2 |= SDHCI_CTRL_UHS_DDR50;
470*4882a593Smuzhiyun 	else if (timing == MMC_TIMING_MMC_HS400 ||
471*4882a593Smuzhiyun 		 timing == MMC_TIMING_MMC_HS400ES)
472*4882a593Smuzhiyun 		ctrl_2 |= SDHCI_CTRL_HS400 | SDHCI_CTRL_DRV_TYPE_A;
473*4882a593Smuzhiyun 
474*4882a593Smuzhiyun 	sdhci_writew(host, ctrl_2, SDHCI_HOST_CONTROL2);
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun 
477*4882a593Smuzhiyun #ifdef CONFIG_DM_MMC
478*4882a593Smuzhiyun static bool sdhci_card_busy(struct udevice *dev)
479*4882a593Smuzhiyun {
480*4882a593Smuzhiyun 	struct mmc *mmc = mmc_get_mmc_dev(dev);
481*4882a593Smuzhiyun #else
482*4882a593Smuzhiyun static bool sdhci_card_busy(struct mmc *mmc)
483*4882a593Smuzhiyun {
484*4882a593Smuzhiyun #endif
485*4882a593Smuzhiyun 	struct sdhci_host *host = mmc->priv;
486*4882a593Smuzhiyun 	u32 present_state;
487*4882a593Smuzhiyun 
488*4882a593Smuzhiyun 	/* Check whether DAT[0] is 0 */
489*4882a593Smuzhiyun 	present_state = sdhci_readl(host, SDHCI_PRESENT_STATE);
490*4882a593Smuzhiyun 
491*4882a593Smuzhiyun 	return !(present_state & SDHCI_DATA_0_LVL);
492*4882a593Smuzhiyun }
493*4882a593Smuzhiyun 
494*4882a593Smuzhiyun #ifdef CONFIG_DM_MMC
495*4882a593Smuzhiyun static int sdhci_set_ios(struct udevice *dev)
496*4882a593Smuzhiyun {
497*4882a593Smuzhiyun 	struct mmc *mmc = mmc_get_mmc_dev(dev);
498*4882a593Smuzhiyun #else
499*4882a593Smuzhiyun static int sdhci_set_ios(struct mmc *mmc)
500*4882a593Smuzhiyun {
501*4882a593Smuzhiyun #endif
502*4882a593Smuzhiyun 	u32 ctrl;
503*4882a593Smuzhiyun 	struct sdhci_host *host = mmc->priv;
504*4882a593Smuzhiyun 
505*4882a593Smuzhiyun 	if (host->ops && host->ops->set_control_reg)
506*4882a593Smuzhiyun 		host->ops->set_control_reg(host);
507*4882a593Smuzhiyun 
508*4882a593Smuzhiyun 	if (mmc->clock != host->clock) {
509*4882a593Smuzhiyun 		if (host->ops && host->ops->set_clock)
510*4882a593Smuzhiyun 			host->ops->set_clock(host, mmc->clock);
511*4882a593Smuzhiyun 		else
512*4882a593Smuzhiyun 			sdhci_set_clock(host, mmc->clock);
513*4882a593Smuzhiyun 	}
514*4882a593Smuzhiyun 
515*4882a593Smuzhiyun 	/* Set bus width */
516*4882a593Smuzhiyun 	ctrl = sdhci_readb(host, SDHCI_HOST_CONTROL);
517*4882a593Smuzhiyun 	if (mmc->bus_width == 8) {
518*4882a593Smuzhiyun 		ctrl &= ~SDHCI_CTRL_4BITBUS;
519*4882a593Smuzhiyun 		if ((SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) ||
520*4882a593Smuzhiyun 				(host->quirks & SDHCI_QUIRK_USE_WIDE8))
521*4882a593Smuzhiyun 			ctrl |= SDHCI_CTRL_8BITBUS;
522*4882a593Smuzhiyun 	} else {
523*4882a593Smuzhiyun 		if ((SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) ||
524*4882a593Smuzhiyun 				(host->quirks & SDHCI_QUIRK_USE_WIDE8))
525*4882a593Smuzhiyun 			ctrl &= ~SDHCI_CTRL_8BITBUS;
526*4882a593Smuzhiyun 		if (mmc->bus_width == 4)
527*4882a593Smuzhiyun 			ctrl |= SDHCI_CTRL_4BITBUS;
528*4882a593Smuzhiyun 		else
529*4882a593Smuzhiyun 			ctrl &= ~SDHCI_CTRL_4BITBUS;
530*4882a593Smuzhiyun 	}
531*4882a593Smuzhiyun 
532*4882a593Smuzhiyun 	if (!(mmc->timing == MMC_TIMING_LEGACY) &&
533*4882a593Smuzhiyun 	    !(host->quirks & SDHCI_QUIRK_NO_HISPD_BIT))
534*4882a593Smuzhiyun 		ctrl |= SDHCI_CTRL_HISPD;
535*4882a593Smuzhiyun 	else
536*4882a593Smuzhiyun 		ctrl &= ~SDHCI_CTRL_HISPD;
537*4882a593Smuzhiyun 
538*4882a593Smuzhiyun 	sdhci_writeb(host, ctrl, SDHCI_HOST_CONTROL);
539*4882a593Smuzhiyun 
540*4882a593Smuzhiyun 	if ((mmc->timing != MMC_TIMING_LEGACY) &&
541*4882a593Smuzhiyun 	    (mmc->timing != MMC_TIMING_MMC_HS) &&
542*4882a593Smuzhiyun 	    (mmc->timing != MMC_TIMING_SD_HS))
543*4882a593Smuzhiyun 		sdhci_set_power(host, MMC_VDD_165_195_SHIFT);
544*4882a593Smuzhiyun 
545*4882a593Smuzhiyun 	sdhci_set_uhs_signaling(host);
546*4882a593Smuzhiyun 
547*4882a593Smuzhiyun 	/* If available, call the driver specific "post" set_ios() function */
548*4882a593Smuzhiyun 	if (host->ops && host->ops->set_ios_post)
549*4882a593Smuzhiyun 		host->ops->set_ios_post(host);
550*4882a593Smuzhiyun 
551*4882a593Smuzhiyun 	return 0;
552*4882a593Smuzhiyun }
553*4882a593Smuzhiyun 
554*4882a593Smuzhiyun static int sdhci_init(struct mmc *mmc)
555*4882a593Smuzhiyun {
556*4882a593Smuzhiyun 	struct sdhci_host *host = mmc->priv;
557*4882a593Smuzhiyun 
558*4882a593Smuzhiyun 	sdhci_reset(host, SDHCI_RESET_ALL);
559*4882a593Smuzhiyun 
560*4882a593Smuzhiyun 	if ((host->quirks & SDHCI_QUIRK_32BIT_DMA_ADDR) && !aligned_buffer) {
561*4882a593Smuzhiyun 		aligned_buffer = memalign(8, 512*1024);
562*4882a593Smuzhiyun 		if (!aligned_buffer) {
563*4882a593Smuzhiyun 			printf("%s: Aligned buffer alloc failed!!!\n",
564*4882a593Smuzhiyun 			       __func__);
565*4882a593Smuzhiyun 			return -ENOMEM;
566*4882a593Smuzhiyun 		}
567*4882a593Smuzhiyun 	}
568*4882a593Smuzhiyun 
569*4882a593Smuzhiyun 	sdhci_set_power(host, fls(mmc->cfg->voltages) - 1);
570*4882a593Smuzhiyun 
571*4882a593Smuzhiyun 	if (host->ops && host->ops->get_cd)
572*4882a593Smuzhiyun 		host->ops->get_cd(host);
573*4882a593Smuzhiyun 
574*4882a593Smuzhiyun 	/* Enable only interrupts served by the SD controller */
575*4882a593Smuzhiyun 	sdhci_writel(host, SDHCI_INT_DATA_MASK | SDHCI_INT_CMD_MASK,
576*4882a593Smuzhiyun 		     SDHCI_INT_ENABLE);
577*4882a593Smuzhiyun 	/* Mask all sdhci interrupt sources */
578*4882a593Smuzhiyun 	sdhci_writel(host, 0x0, SDHCI_SIGNAL_ENABLE);
579*4882a593Smuzhiyun 
580*4882a593Smuzhiyun 	return 0;
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun 
583*4882a593Smuzhiyun static int sdhci_send_tuning(struct sdhci_host *host, u32 opcode)
584*4882a593Smuzhiyun {
585*4882a593Smuzhiyun 	struct mmc_cmd cmd;
586*4882a593Smuzhiyun 
587*4882a593Smuzhiyun 	cmd.cmdidx = opcode;
588*4882a593Smuzhiyun 	cmd.resp_type = MMC_RSP_R1;
589*4882a593Smuzhiyun 	cmd.cmdarg = 0;
590*4882a593Smuzhiyun 	/*
591*4882a593Smuzhiyun 	 * In response to CMD19, the card sends 64 bytes of tuning
592*4882a593Smuzhiyun 	 * block to the Host Controller. So we set the block size
593*4882a593Smuzhiyun 	 * to 64 here.
594*4882a593Smuzhiyun 	 */
595*4882a593Smuzhiyun 	if (opcode == MMC_SEND_TUNING_BLOCK_HS200 &&
596*4882a593Smuzhiyun 	    host->mmc->bus_width == MMC_BUS_WIDTH_8BIT)
597*4882a593Smuzhiyun 		sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 128), SDHCI_BLOCK_SIZE);
598*4882a593Smuzhiyun 	else
599*4882a593Smuzhiyun 		sdhci_writew(host, SDHCI_MAKE_BLKSZ(7, 64), SDHCI_BLOCK_SIZE);
600*4882a593Smuzhiyun 
601*4882a593Smuzhiyun 	/*
602*4882a593Smuzhiyun 	 * The tuning block is sent by the card to the host controller.
603*4882a593Smuzhiyun 	 * So we set the TRNS_READ bit in the Transfer Mode register.
604*4882a593Smuzhiyun 	 * This also takes care of setting DMA Enable and Multi Block
605*4882a593Smuzhiyun 	 * Select in the same register to 0.
606*4882a593Smuzhiyun 	 */
607*4882a593Smuzhiyun 	sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE);
608*4882a593Smuzhiyun 
609*4882a593Smuzhiyun #ifdef CONFIG_DM_MMC
610*4882a593Smuzhiyun 	return sdhci_send_command(host->mmc->dev, &cmd, NULL);
611*4882a593Smuzhiyun #else
612*4882a593Smuzhiyun 	return sdhci_send_command(host->mmc, &cmd, NULL);
613*4882a593Smuzhiyun #endif
614*4882a593Smuzhiyun }
615*4882a593Smuzhiyun 
616*4882a593Smuzhiyun #define MAX_TUNING_LOOP 40
617*4882a593Smuzhiyun static int __sdhci_execute_tuning(struct sdhci_host *host, u32 opcode)
618*4882a593Smuzhiyun {
619*4882a593Smuzhiyun 	int i;
620*4882a593Smuzhiyun 	int ret;
621*4882a593Smuzhiyun 
622*4882a593Smuzhiyun 	/*
623*4882a593Smuzhiyun 	 * Issue opcode repeatedly till Execute Tuning is set to 0 or the number
624*4882a593Smuzhiyun 	 * of loops reaches 40 times.
625*4882a593Smuzhiyun 	 */
626*4882a593Smuzhiyun 	for (i = 0; i < MAX_TUNING_LOOP; i++) {
627*4882a593Smuzhiyun 		u16 ctrl;
628*4882a593Smuzhiyun 
629*4882a593Smuzhiyun 		ret = sdhci_send_tuning(host, opcode);
630*4882a593Smuzhiyun 
631*4882a593Smuzhiyun 		if (ret)
632*4882a593Smuzhiyun 			return ret;
633*4882a593Smuzhiyun 
634*4882a593Smuzhiyun 		ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
635*4882a593Smuzhiyun 		if (!(ctrl & SDHCI_CTRL_EXEC_TUNING)) {
636*4882a593Smuzhiyun 			if (ctrl & SDHCI_CTRL_TUNED_CLK)
637*4882a593Smuzhiyun 				/* Tuning successfully */
638*4882a593Smuzhiyun 				return 0;
639*4882a593Smuzhiyun 			break;
640*4882a593Smuzhiyun 		}
641*4882a593Smuzhiyun 	}
642*4882a593Smuzhiyun 
643*4882a593Smuzhiyun 	return -ETIMEDOUT;
644*4882a593Smuzhiyun }
645*4882a593Smuzhiyun 
646*4882a593Smuzhiyun #ifdef CONFIG_DM_MMC
647*4882a593Smuzhiyun static int sdhci_execute_tuning(struct udevice *dev, u32 opcode)
648*4882a593Smuzhiyun {
649*4882a593Smuzhiyun 	struct mmc *mmc = mmc_get_mmc_dev(dev);
650*4882a593Smuzhiyun #else
651*4882a593Smuzhiyun static int sdhci_execute_tuning(struct mmc *mmc, u32 opcode)
652*4882a593Smuzhiyun {
653*4882a593Smuzhiyun #endif
654*4882a593Smuzhiyun 	struct sdhci_host *host = mmc->priv;
655*4882a593Smuzhiyun 	u16 ctrl;
656*4882a593Smuzhiyun 
657*4882a593Smuzhiyun 	/*
658*4882a593Smuzhiyun 	 * The Host Controller needs tuning in case of SDR104 and DDR50
659*4882a593Smuzhiyun 	 * mode, and for SDR50 mode when Use Tuning for SDR50 is set in
660*4882a593Smuzhiyun 	 * the Capabilities register.
661*4882a593Smuzhiyun 	 * If the Host Controller supports the HS200 mode then the
662*4882a593Smuzhiyun 	 * tuning function has to be executed.
663*4882a593Smuzhiyun 	 */
664*4882a593Smuzhiyun 	switch (mmc->timing) {
665*4882a593Smuzhiyun 	/* HS400 tuning is done in HS200 mode */
666*4882a593Smuzhiyun 	case MMC_TIMING_MMC_HS400:
667*4882a593Smuzhiyun 		return -EINVAL;
668*4882a593Smuzhiyun 	case MMC_TIMING_MMC_HS200:
669*4882a593Smuzhiyun 		/*
670*4882a593Smuzhiyun 		 * Periodic re-tuning for HS400 is not expected to be needed, so
671*4882a593Smuzhiyun 		 * disable it here.
672*4882a593Smuzhiyun 		 */
673*4882a593Smuzhiyun 		break;
674*4882a593Smuzhiyun 	default:
675*4882a593Smuzhiyun 		return -EINVAL;
676*4882a593Smuzhiyun 	}
677*4882a593Smuzhiyun 
678*4882a593Smuzhiyun 	ctrl = sdhci_readw(host, SDHCI_HOST_CONTROL2);
679*4882a593Smuzhiyun 	ctrl |= SDHCI_CTRL_EXEC_TUNING;
680*4882a593Smuzhiyun 	sdhci_writew(host, ctrl, SDHCI_HOST_CONTROL2);
681*4882a593Smuzhiyun 
682*4882a593Smuzhiyun 	return __sdhci_execute_tuning(host, opcode);
683*4882a593Smuzhiyun }
684*4882a593Smuzhiyun 
685*4882a593Smuzhiyun #ifdef CONFIG_DM_MMC
686*4882a593Smuzhiyun int sdhci_probe(struct udevice *dev)
687*4882a593Smuzhiyun {
688*4882a593Smuzhiyun 	struct mmc *mmc = mmc_get_mmc_dev(dev);
689*4882a593Smuzhiyun 
690*4882a593Smuzhiyun 	return sdhci_init(mmc);
691*4882a593Smuzhiyun }
692*4882a593Smuzhiyun 
693*4882a593Smuzhiyun static int sdhci_set_enhanced_strobe(struct udevice *dev)
694*4882a593Smuzhiyun {
695*4882a593Smuzhiyun 	struct mmc *mmc = mmc_get_mmc_dev(dev);
696*4882a593Smuzhiyun 	struct sdhci_host *host = mmc->priv;
697*4882a593Smuzhiyun 
698*4882a593Smuzhiyun 	if (host->ops && host->ops->set_enhanced_strobe)
699*4882a593Smuzhiyun 		return host->ops->set_enhanced_strobe(host);
700*4882a593Smuzhiyun 
701*4882a593Smuzhiyun 	return -ENOTSUPP;
702*4882a593Smuzhiyun }
703*4882a593Smuzhiyun 
704*4882a593Smuzhiyun const struct dm_mmc_ops sdhci_ops = {
705*4882a593Smuzhiyun 	.card_busy	= sdhci_card_busy,
706*4882a593Smuzhiyun 	.send_cmd	= sdhci_send_command,
707*4882a593Smuzhiyun 	.set_ios	= sdhci_set_ios,
708*4882a593Smuzhiyun 	.execute_tuning = sdhci_execute_tuning,
709*4882a593Smuzhiyun 	.set_enhanced_strobe = sdhci_set_enhanced_strobe,
710*4882a593Smuzhiyun };
711*4882a593Smuzhiyun #else
712*4882a593Smuzhiyun static const struct mmc_ops sdhci_ops = {
713*4882a593Smuzhiyun 	.card_busy	= sdhci_card_busy,
714*4882a593Smuzhiyun 	.send_cmd	= sdhci_send_command,
715*4882a593Smuzhiyun 	.set_ios	= sdhci_set_ios,
716*4882a593Smuzhiyun 	.init		= sdhci_init,
717*4882a593Smuzhiyun 	.execute_tuning = sdhci_execute_tuning,
718*4882a593Smuzhiyun };
719*4882a593Smuzhiyun #endif
720*4882a593Smuzhiyun 
721*4882a593Smuzhiyun int sdhci_setup_cfg(struct mmc_config *cfg, struct sdhci_host *host,
722*4882a593Smuzhiyun 		u32 f_max, u32 f_min)
723*4882a593Smuzhiyun {
724*4882a593Smuzhiyun 	u32 caps, caps_1;
725*4882a593Smuzhiyun 
726*4882a593Smuzhiyun 	caps = sdhci_readl(host, SDHCI_CAPABILITIES);
727*4882a593Smuzhiyun 
728*4882a593Smuzhiyun #ifdef CONFIG_MMC_SDHCI_SDMA
729*4882a593Smuzhiyun 	if (!(caps & SDHCI_CAN_DO_SDMA)) {
730*4882a593Smuzhiyun 		printf("%s: Your controller doesn't support SDMA!!\n",
731*4882a593Smuzhiyun 		       __func__);
732*4882a593Smuzhiyun 		return -EINVAL;
733*4882a593Smuzhiyun 	}
734*4882a593Smuzhiyun #endif
735*4882a593Smuzhiyun 	if (host->quirks & SDHCI_QUIRK_REG32_RW)
736*4882a593Smuzhiyun 		host->version =
737*4882a593Smuzhiyun 			sdhci_readl(host, SDHCI_HOST_VERSION - 2) >> 16;
738*4882a593Smuzhiyun 	else
739*4882a593Smuzhiyun 		host->version = sdhci_readw(host, SDHCI_HOST_VERSION);
740*4882a593Smuzhiyun 
741*4882a593Smuzhiyun 	cfg->name = host->name;
742*4882a593Smuzhiyun #ifndef CONFIG_DM_MMC
743*4882a593Smuzhiyun 	cfg->ops = &sdhci_ops;
744*4882a593Smuzhiyun #endif
745*4882a593Smuzhiyun 
746*4882a593Smuzhiyun 	/* Check whether the clock multiplier is supported or not */
747*4882a593Smuzhiyun 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
748*4882a593Smuzhiyun 		caps_1 = sdhci_readl(host, SDHCI_CAPABILITIES_1);
749*4882a593Smuzhiyun 		host->clk_mul = (caps_1 & SDHCI_CLOCK_MUL_MASK) >>
750*4882a593Smuzhiyun 				SDHCI_CLOCK_MUL_SHIFT;
751*4882a593Smuzhiyun 	}
752*4882a593Smuzhiyun 
753*4882a593Smuzhiyun 	if (host->max_clk == 0) {
754*4882a593Smuzhiyun 		if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
755*4882a593Smuzhiyun 			host->max_clk = (caps & SDHCI_CLOCK_V3_BASE_MASK) >>
756*4882a593Smuzhiyun 				SDHCI_CLOCK_BASE_SHIFT;
757*4882a593Smuzhiyun 		else
758*4882a593Smuzhiyun 			host->max_clk = (caps & SDHCI_CLOCK_BASE_MASK) >>
759*4882a593Smuzhiyun 				SDHCI_CLOCK_BASE_SHIFT;
760*4882a593Smuzhiyun 		host->max_clk *= 1000000;
761*4882a593Smuzhiyun 		if (host->clk_mul)
762*4882a593Smuzhiyun 			host->max_clk *= host->clk_mul;
763*4882a593Smuzhiyun 	}
764*4882a593Smuzhiyun 	if (host->max_clk == 0) {
765*4882a593Smuzhiyun 		printf("%s: Hardware doesn't specify base clock frequency\n",
766*4882a593Smuzhiyun 		       __func__);
767*4882a593Smuzhiyun 		return -EINVAL;
768*4882a593Smuzhiyun 	}
769*4882a593Smuzhiyun 	if (f_max && (f_max < host->max_clk))
770*4882a593Smuzhiyun 		cfg->f_max = f_max;
771*4882a593Smuzhiyun 	else
772*4882a593Smuzhiyun 		cfg->f_max = host->max_clk;
773*4882a593Smuzhiyun 	if (f_min)
774*4882a593Smuzhiyun 		cfg->f_min = f_min;
775*4882a593Smuzhiyun 	else {
776*4882a593Smuzhiyun 		if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300)
777*4882a593Smuzhiyun 			cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_300;
778*4882a593Smuzhiyun 		else
779*4882a593Smuzhiyun 			cfg->f_min = cfg->f_max / SDHCI_MAX_DIV_SPEC_200;
780*4882a593Smuzhiyun 	}
781*4882a593Smuzhiyun 	cfg->voltages = 0;
782*4882a593Smuzhiyun 	if (caps & SDHCI_CAN_VDD_330)
783*4882a593Smuzhiyun 		cfg->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
784*4882a593Smuzhiyun 	if (caps & SDHCI_CAN_VDD_300)
785*4882a593Smuzhiyun 		cfg->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
786*4882a593Smuzhiyun 	if (caps & SDHCI_CAN_VDD_180)
787*4882a593Smuzhiyun 		cfg->voltages |= MMC_VDD_165_195;
788*4882a593Smuzhiyun 
789*4882a593Smuzhiyun 	if (host->quirks & SDHCI_QUIRK_BROKEN_VOLTAGE)
790*4882a593Smuzhiyun 		cfg->voltages |= host->voltages;
791*4882a593Smuzhiyun 
792*4882a593Smuzhiyun 	cfg->host_caps = MMC_MODE_HS | MMC_MODE_HS_52MHz | MMC_MODE_4BIT;
793*4882a593Smuzhiyun 
794*4882a593Smuzhiyun 	/* Since Host Controller Version3.0 */
795*4882a593Smuzhiyun 	if (SDHCI_GET_VERSION(host) >= SDHCI_SPEC_300) {
796*4882a593Smuzhiyun 		if (!(caps & SDHCI_CAN_DO_8BIT))
797*4882a593Smuzhiyun 			cfg->host_caps &= ~MMC_MODE_8BIT;
798*4882a593Smuzhiyun 	}
799*4882a593Smuzhiyun 
800*4882a593Smuzhiyun 	if (host->host_caps)
801*4882a593Smuzhiyun 		cfg->host_caps |= host->host_caps;
802*4882a593Smuzhiyun 
803*4882a593Smuzhiyun 	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
804*4882a593Smuzhiyun 
805*4882a593Smuzhiyun 	return 0;
806*4882a593Smuzhiyun }
807*4882a593Smuzhiyun 
808*4882a593Smuzhiyun #ifdef CONFIG_BLK
809*4882a593Smuzhiyun int sdhci_bind(struct udevice *dev, struct mmc *mmc, struct mmc_config *cfg)
810*4882a593Smuzhiyun {
811*4882a593Smuzhiyun 	return mmc_bind(dev, mmc, cfg);
812*4882a593Smuzhiyun }
813*4882a593Smuzhiyun #else
814*4882a593Smuzhiyun int add_sdhci(struct sdhci_host *host, u32 f_max, u32 f_min)
815*4882a593Smuzhiyun {
816*4882a593Smuzhiyun 	int ret;
817*4882a593Smuzhiyun 
818*4882a593Smuzhiyun 	ret = sdhci_setup_cfg(&host->cfg, host, f_max, f_min);
819*4882a593Smuzhiyun 	if (ret)
820*4882a593Smuzhiyun 		return ret;
821*4882a593Smuzhiyun 
822*4882a593Smuzhiyun 	host->mmc = mmc_create(&host->cfg, host);
823*4882a593Smuzhiyun 	if (host->mmc == NULL) {
824*4882a593Smuzhiyun 		printf("%s: mmc create fail!\n", __func__);
825*4882a593Smuzhiyun 		return -ENOMEM;
826*4882a593Smuzhiyun 	}
827*4882a593Smuzhiyun 
828*4882a593Smuzhiyun 	return 0;
829*4882a593Smuzhiyun }
830*4882a593Smuzhiyun #endif
831