fsl_esdhc.c 39.1 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0+
2
/*
3
 * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc
4 5 6 7 8 9 10 11 12 13
 * Andy Fleming
 *
 * Based vaguely on the pxa mmc code:
 * (C) Copyright 2003
 * Kyle Harris, Nexus Technologies, Inc. kharris@nexus-tech.net
 */

#include <config.h>
#include <common.h>
#include <command.h>
14
#include <errno.h>
15
#include <hwconfig.h>
16 17
#include <mmc.h>
#include <part.h>
18
#include <power/regulator.h>
19 20
#include <malloc.h>
#include <fsl_esdhc.h>
21
#include <fdt_support.h>
22
#include <asm/io.h>
P
Peng Fan 已提交
23 24
#include <dm.h>
#include <asm-generic/gpio.h>
25
#include <dm/pinctrl.h>
26 27 28

DECLARE_GLOBAL_DATA_PTR;

29 30 31 32 33 34
#define SDHCI_IRQ_EN_BITS		(IRQSTATEN_CC | IRQSTATEN_TC | \
				IRQSTATEN_CINT | \
				IRQSTATEN_CTOE | IRQSTATEN_CCE | IRQSTATEN_CEBE | \
				IRQSTATEN_CIE | IRQSTATEN_DTOE | IRQSTATEN_DCE | \
				IRQSTATEN_DEBE | IRQSTATEN_BRR | IRQSTATEN_BWR | \
				IRQSTATEN_DINT)
35
#define MAX_TUNING_LOOP 40
36

37
struct fsl_esdhc {
38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60
	uint    dsaddr;		/* SDMA system address register */
	uint    blkattr;	/* Block attributes register */
	uint    cmdarg;		/* Command argument register */
	uint    xfertyp;	/* Transfer type register */
	uint    cmdrsp0;	/* Command response 0 register */
	uint    cmdrsp1;	/* Command response 1 register */
	uint    cmdrsp2;	/* Command response 2 register */
	uint    cmdrsp3;	/* Command response 3 register */
	uint    datport;	/* Buffer data port register */
	uint    prsstat;	/* Present state register */
	uint    proctl;		/* Protocol control register */
	uint    sysctl;		/* System Control Register */
	uint    irqstat;	/* Interrupt status register */
	uint    irqstaten;	/* Interrupt status enable register */
	uint    irqsigen;	/* Interrupt signal enable register */
	uint    autoc12err;	/* Auto CMD error status register */
	uint    hostcapblt;	/* Host controller capabilities register */
	uint    wml;		/* Watermark level register */
	uint    mixctrl;	/* For USDHC */
	char    reserved1[4];	/* reserved */
	uint    fevt;		/* Force event register */
	uint    admaes;		/* ADMA error status register */
	uint    adsaddr;	/* ADMA system address register */
61 62 63 64
	char    reserved2[4];
	uint    dllctrl;
	uint    dllstat;
	uint    clktunectrlstatus;
65 66 67 68
	char    reserved3[4];
	uint	strobe_dllctrl;
	uint	strobe_dllstat;
	char    reserved4[72];
69 70 71
	uint    vendorspec;
	uint    mmcboot;
	uint    vendorspec2;
72 73
	uint    tuning_ctrl;	/* on i.MX6/7/8 */
	char	reserved5[44];
74
	uint    hostver;	/* Host controller version register */
75
	char    reserved6[4];	/* reserved */
76
	uint    dmaerraddr;	/* DMA error address register */
77
	char    reserved7[4];	/* reserved */
78 79
	uint    dmaerrattr;	/* DMA error attribute register */
	char    reserved8[4];	/* reserved */
80
	uint    hostcapblt2;	/* Host controller capabilities register 2 */
81
	char    reserved9[8];	/* reserved */
82
	uint    tcr;		/* Tuning control register */
83
	char    reserved10[28];	/* reserved */
84
	uint    sddirctl;	/* SD direction control register */
85
	char    reserved11[712];/* reserved */
86
	uint    scr;		/* eSDHC control register */
87 88
};

89 90 91 92 93
struct fsl_esdhc_plat {
	struct mmc_config cfg;
	struct mmc mmc;
};

94 95 96 97 98
struct esdhc_soc_data {
	u32 flags;
	u32 caps;
};

P
Peng Fan 已提交
99 100 101 102 103 104 105 106 107 108 109
/**
 * struct fsl_esdhc_priv
 *
 * @esdhc_regs: registers of the sdhc controller
 * @sdhc_clk: Current clk of the sdhc controller
 * @bus_width: bus width, 1bit, 4bit or 8bit
 * @cfg: mmc config
 * @mmc: mmc
 * Following is used when Driver Model is enabled for MMC
 * @dev: pointer for the device
 * @non_removable: 0: removable; 1: non-removable
P
Peng Fan 已提交
110
 * @wp_enable: 1: enable checking wp; 0: no check
111
 * @vs18_enable: 1: use 1.8V voltage; 0: use 3.3V
112 113 114 115 116 117
 * @flags: ESDHC_FLAG_xx in include/fsl_esdhc.h
 * @caps: controller capabilities
 * @tuning_step: tuning step setting in tuning_ctrl register
 * @start_tuning_tap: the start point for tuning in tuning_ctrl register
 * @strobe_dll_delay_target: settings in strobe_dllctrl
 * @signal_voltage: indicating the current voltage
P
Peng Fan 已提交
118
 * @cd_gpio: gpio for card detection
P
Peng Fan 已提交
119
 * @wp_gpio: gpio for write protection
P
Peng Fan 已提交
120 121 122 123
 */
struct fsl_esdhc_priv {
	struct fsl_esdhc *esdhc_regs;
	unsigned int sdhc_clk;
124 125
	unsigned int clock;
	unsigned int mode;
P
Peng Fan 已提交
126
	unsigned int bus_width;
127
#if !CONFIG_IS_ENABLED(BLK)
P
Peng Fan 已提交
128
	struct mmc *mmc;
129
#endif
P
Peng Fan 已提交
130 131
	struct udevice *dev;
	int non_removable;
P
Peng Fan 已提交
132
	int wp_enable;
133
	int vs18_enable;
134 135 136 137 138 139 140 141 142 143
	u32 flags;
	u32 caps;
	u32 tuning_step;
	u32 tuning_start_tap;
	u32 strobe_dll_delay_target;
	u32 signal_voltage;
#if IS_ENABLED(CONFIG_DM_REGULATOR)
	struct udevice *vqmmc_dev;
	struct udevice *vmmc_dev;
#endif
144
#ifdef CONFIG_DM_GPIO
P
Peng Fan 已提交
145
	struct gpio_desc cd_gpio;
P
Peng Fan 已提交
146
	struct gpio_desc wp_gpio;
147
#endif
P
Peng Fan 已提交
148 149
};

150
/* Return the XFERTYP flags for a given command and data packet */
151
static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
152 153 154 155
{
	uint xfertyp = 0;

	if (data) {
156 157 158 159
		xfertyp |= XFERTYP_DPSEL;
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
		xfertyp |= XFERTYP_DMAEN;
#endif
160 161 162
		if (data->blocks > 1) {
			xfertyp |= XFERTYP_MSBSEL;
			xfertyp |= XFERTYP_BCEN;
163 164 165
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
			xfertyp |= XFERTYP_AC12EN;
#endif
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182
		}

		if (data->flags & MMC_DATA_READ)
			xfertyp |= XFERTYP_DTDSEL;
	}

	if (cmd->resp_type & MMC_RSP_CRC)
		xfertyp |= XFERTYP_CCCEN;
	if (cmd->resp_type & MMC_RSP_OPCODE)
		xfertyp |= XFERTYP_CICEN;
	if (cmd->resp_type & MMC_RSP_136)
		xfertyp |= XFERTYP_RSPTYP_136;
	else if (cmd->resp_type & MMC_RSP_BUSY)
		xfertyp |= XFERTYP_RSPTYP_48_BUSY;
	else if (cmd->resp_type & MMC_RSP_PRESENT)
		xfertyp |= XFERTYP_RSPTYP_48;

183 184
	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
		xfertyp |= XFERTYP_CMDTYP_ABORT;
185

186 187 188
	return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
}

189 190 191 192
#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
/*
 * PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
 */
193 194
static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv,
				 struct mmc_data *data)
195
{
P
Peng Fan 已提交
196
	struct fsl_esdhc *regs = priv->esdhc_regs;
197 198 199 200 201
	uint blocks;
	char *buffer;
	uint databuf;
	uint size;
	uint irqstat;
202
	ulong start;
203 204 205 206 207

	if (data->flags & MMC_DATA_READ) {
		blocks = data->blocks;
		buffer = data->dest;
		while (blocks) {
208
			start = get_timer(0);
209 210
			size = data->blocksize;
			irqstat = esdhc_read32(&regs->irqstat);
211 212 213 214 215
			while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BREN)) {
				if (get_timer(start) > PIO_TIMEOUT) {
					printf("\nData Read Failed in PIO Mode.");
					return;
				}
216 217 218 219 220 221 222 223 224 225 226 227 228
			}
			while (size && (!(irqstat & IRQSTAT_TC))) {
				udelay(100); /* Wait before last byte transfer complete */
				irqstat = esdhc_read32(&regs->irqstat);
				databuf = in_le32(&regs->datport);
				*((uint *)buffer) = databuf;
				buffer += 4;
				size -= 4;
			}
			blocks--;
		}
	} else {
		blocks = data->blocks;
229
		buffer = (char *)data->src;
230
		while (blocks) {
231
			start = get_timer(0);
232 233
			size = data->blocksize;
			irqstat = esdhc_read32(&regs->irqstat);
234 235 236 237 238
			while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)) {
				if (get_timer(start) > PIO_TIMEOUT) {
					printf("\nData Write Failed in PIO Mode.");
					return;
				}
239 240 241 242 243 244 245 246 247 248 249 250 251 252 253
			}
			while (size && (!(irqstat & IRQSTAT_TC))) {
				udelay(100); /* Wait before last byte transfer complete */
				databuf = *((uint *)buffer);
				buffer += 4;
				size -= 4;
				irqstat = esdhc_read32(&regs->irqstat);
				out_le32(&regs->datport, databuf);
			}
			blocks--;
		}
	}
}
#endif

254 255
static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
			    struct mmc_data *data)
256 257
{
	int timeout;
P
Peng Fan 已提交
258
	struct fsl_esdhc *regs = priv->esdhc_regs;
P
Peng Fan 已提交
259 260
#if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
	defined(CONFIG_MX8M)
261 262
	dma_addr_t addr;
#endif
263
	uint wml_value;
264 265 266 267

	wml_value = data->blocksize/4;

	if (data->flags & MMC_DATA_READ) {
268 269
		if (wml_value > WML_RD_WML_MAX)
			wml_value = WML_RD_WML_MAX_VAL;
270

271
		esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
272
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
P
Peng Fan 已提交
273 274
#if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
	defined(CONFIG_MX8M)
275 276 277 278 279 280
		addr = virt_to_phys((void *)(data->dest));
		if (upper_32_bits(addr))
			printf("Error found for upper 32 bits\n");
		else
			esdhc_write32(&regs->dsaddr, lower_32_bits(addr));
#else
281
		esdhc_write32(&regs->dsaddr, (u32)data->dest);
282
#endif
283
#endif
284
	} else {
285
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
286 287 288
		flush_dcache_range((ulong)data->src,
				   (ulong)data->src+data->blocks
					 *data->blocksize);
289
#endif
290 291
		if (wml_value > WML_WR_WML_MAX)
			wml_value = WML_WR_WML_MAX_VAL;
P
Peng Fan 已提交
292 293 294 295
		if (priv->wp_enable) {
			if ((esdhc_read32(&regs->prsstat) &
			    PRSSTAT_WPSPL) == 0) {
				printf("\nThe SD card is locked. Can not write to a locked card.\n\n");
296
				return -ETIMEDOUT;
P
Peng Fan 已提交
297
			}
298
		}
299 300 301

		esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
					wml_value << 16);
302
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
P
Peng Fan 已提交
303 304
#if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
	defined(CONFIG_MX8M)
305 306 307 308 309 310
		addr = virt_to_phys((void *)(data->src));
		if (upper_32_bits(addr))
			printf("Error found for upper 32 bits\n");
		else
			esdhc_write32(&regs->dsaddr, lower_32_bits(addr));
#else
311
		esdhc_write32(&regs->dsaddr, (u32)data->src);
312
#endif
313
#endif
314 315
	}

316
	esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
317 318

	/* Calculate the timeout period for data transactions */
319 320 321 322 323
	/*
	 * 1)Timeout period = (2^(timeout+13)) SD Clock cycles
	 * 2)Timeout period should be minimum 0.250sec as per SD Card spec
	 *  So, Number of SD Clock cycles for 0.25sec should be minimum
	 *		(SD Clock/sec * 0.25 sec) SD Clock cycles
324
	 *		= (mmc->clock * 1/4) SD Clock cycles
325
	 * As 1) >=  2)
326
	 * => (2^(timeout+13)) >= mmc->clock * 1/4
327
	 * Taking log2 both the sides
328
	 * => timeout + 13 >= log2(mmc->clock/4)
329
	 * Rounding up to next power of 2
330 331
	 * => timeout + 13 = log2(mmc->clock/4) + 1
	 * => timeout + 13 = fls(mmc->clock/4)
332 333 334 335 336 337 338
	 *
	 * However, the MMC spec "It is strongly recommended for hosts to
	 * implement more than 500ms timeout value even if the card
	 * indicates the 250ms maximum busy length."  Even the previous
	 * value of 300ms is known to be insufficient for some cards.
	 * So, we use
	 * => timeout + 13 = fls(mmc->clock/2)
339
	 */
340
	timeout = fls(mmc->clock/2);
341 342 343 344 345 346 347 348
	timeout -= 13;

	if (timeout > 14)
		timeout = 14;

	if (timeout < 0)
		timeout = 0;

349 350 351 352 353
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC_A001
	if ((timeout == 4) || (timeout == 8) || (timeout == 12))
		timeout++;
#endif

354 355 356
#ifdef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE
	timeout = 0xE;
#endif
357
	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, timeout << 16);
358 359 360 361

	return 0;
}

362 363 364
static void check_and_invalidate_dcache_range
	(struct mmc_cmd *cmd,
	 struct mmc_data *data) {
365
	unsigned start = 0;
366
	unsigned end = 0;
367 368
	unsigned size = roundup(ARCH_DMA_MINALIGN,
				data->blocks*data->blocksize);
P
Peng Fan 已提交
369 370
#if defined(CONFIG_FSL_LAYERSCAPE) || defined(CONFIG_S32V234) || \
	defined(CONFIG_MX8M)
371 372 373 374 375 376 377
	dma_addr_t addr;

	addr = virt_to_phys((void *)(data->dest));
	if (upper_32_bits(addr))
		printf("Error found for upper 32 bits\n");
	else
		start = lower_32_bits(addr);
378 379
#else
	start = (unsigned)data->dest;
380
#endif
381
	end = start + size;
382 383
	invalidate_dcache_range(start, end);
}
384

385 386 387 388
/*
 * Sends a command out on the bus.  Takes the mmc pointer,
 * a command pointer, and an optional data pointer.
 */
389 390
static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
				 struct mmc_cmd *cmd, struct mmc_data *data)
391
{
392
	int	err = 0;
393 394
	uint	xfertyp;
	uint	irqstat;
395
	u32	flags = IRQSTAT_CC | IRQSTAT_CTOE;
P
Peng Fan 已提交
396
	struct fsl_esdhc *regs = priv->esdhc_regs;
397

398 399 400 401 402
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
		return 0;
#endif

403
	esdhc_write32(&regs->irqstat, -1);
404 405 406 407

	sync();

	/* Wait for the bus to be idle */
408 409 410
	while ((esdhc_read32(&regs->prsstat) & PRSSTAT_CICHB) ||
			(esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB))
		;
411

412 413
	while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA)
		;
414 415 416 417 418 419 420 421 422 423

	/* Wait at least 8 SD clock cycles before the next command */
	/*
	 * Note: This is way more than 8 cycles, but 1ms seems to
	 * resolve timing issues with some cards
	 */
	udelay(1000);

	/* Set up for a data transfer if we have one */
	if (data) {
424
		err = esdhc_setup_data(priv, mmc, data);
425 426
		if(err)
			return err;
427 428 429

		if (data->flags & MMC_DATA_READ)
			check_and_invalidate_dcache_range(cmd, data);
430 431 432 433 434
	}

	/* Figure out the transfer arguments */
	xfertyp = esdhc_xfertyp(cmd, data);

435 436 437
	/* Mask all irqs */
	esdhc_write32(&regs->irqsigen, 0);

438
	/* Send the command */
439
	esdhc_write32(&regs->cmdarg, cmd->cmdarg);
440 441
#if defined(CONFIG_FSL_USDHC)
	esdhc_write32(&regs->mixctrl,
442 443
	(esdhc_read32(&regs->mixctrl) & 0xFFFFFF80) | (xfertyp & 0x7F)
			| (mmc->ddr_mode ? XFERTYP_DDREN : 0));
444 445
	esdhc_write32(&regs->xfertyp, xfertyp & 0xFFFF0000);
#else
446
	esdhc_write32(&regs->xfertyp, xfertyp);
447
#endif
448

449 450 451 452
	if ((cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK) ||
	    (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200))
		flags = IRQSTAT_BRR;

453
	/* Wait for the command to complete */
454
	while (!(esdhc_read32(&regs->irqstat) & flags))
455
		;
456

457
	irqstat = esdhc_read32(&regs->irqstat);
458

459
	if (irqstat & CMD_ERR) {
460
		err = -ECOMM;
461
		goto out;
462 463
	}

464
	if (irqstat & IRQSTAT_CTOE) {
465
		err = -ETIMEDOUT;
466 467
		goto out;
	}
468

469 470 471 472 473 474 475 476 477
	/* Switch voltage to 1.8V if CMD11 succeeded */
	if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V) {
		esdhc_setbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);

		printf("Run CMD11 1.8V switch\n");
		/* Sleep for 5 ms - max time for card to switch to 1.8V */
		udelay(5000);
	}

478 479
	/* Workaround for ESDHC errata ENGcm03648 */
	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
480
		int timeout = 6000;
481

482
		/* Poll on DATA0 line for cmd with busy signal for 600 ms */
483 484 485 486 487 488 489 490
		while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
					PRSSTAT_DAT0)) {
			udelay(100);
			timeout--;
		}

		if (timeout <= 0) {
			printf("Timeout waiting for DAT0 to go high!\n");
491
			err = -ETIMEDOUT;
492
			goto out;
493 494 495
		}
	}

496 497 498 499
	/* Copy the response to the response buffer */
	if (cmd->resp_type & MMC_RSP_136) {
		u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;

500 501 502 503
		cmdrsp3 = esdhc_read32(&regs->cmdrsp3);
		cmdrsp2 = esdhc_read32(&regs->cmdrsp2);
		cmdrsp1 = esdhc_read32(&regs->cmdrsp1);
		cmdrsp0 = esdhc_read32(&regs->cmdrsp0);
R
Rabin Vincent 已提交
504 505 506 507
		cmd->response[0] = (cmdrsp3 << 8) | (cmdrsp2 >> 24);
		cmd->response[1] = (cmdrsp2 << 8) | (cmdrsp1 >> 24);
		cmd->response[2] = (cmdrsp1 << 8) | (cmdrsp0 >> 24);
		cmd->response[3] = (cmdrsp0 << 8);
508
	} else
509
		cmd->response[0] = esdhc_read32(&regs->cmdrsp0);
510 511 512

	/* Wait until all of the blocks are transferred */
	if (data) {
513
#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
514
		esdhc_pio_read_write(priv, data);
515
#else
516 517 518 519 520 521
		flags = DATA_COMPLETE;
		if ((cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK) ||
		    (cmd->cmdidx == MMC_CMD_SEND_TUNING_BLOCK_HS200)) {
			flags = IRQSTAT_BRR;
		}

522
		do {
523
			irqstat = esdhc_read32(&regs->irqstat);
524

525
			if (irqstat & IRQSTAT_DTOE) {
526
				err = -ETIMEDOUT;
527 528
				goto out;
			}
529

530
			if (irqstat & DATA_ERR) {
531
				err = -ECOMM;
532 533
				goto out;
			}
534
		} while ((irqstat & flags) != flags);
535

536 537 538 539 540
		/*
		 * Need invalidate the dcache here again to avoid any
		 * cache-fill during the DMA operations such as the
		 * speculative pre-fetching etc.
		 */
541 542
		if (data->flags & MMC_DATA_READ)
			check_and_invalidate_dcache_range(cmd, data);
543
#endif
544 545
	}

546 547 548 549 550 551 552 553 554 555 556 557 558 559 560
out:
	/* Reset CMD and DATA portions on error */
	if (err) {
		esdhc_write32(&regs->sysctl, esdhc_read32(&regs->sysctl) |
			      SYSCTL_RSTC);
		while (esdhc_read32(&regs->sysctl) & SYSCTL_RSTC)
			;

		if (data) {
			esdhc_write32(&regs->sysctl,
				      esdhc_read32(&regs->sysctl) |
				      SYSCTL_RSTD);
			while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTD))
				;
		}
561 562 563 564

		/* If this was CMD11, then notify that power cycle is needed */
		if (cmd->cmdidx == SD_CMD_SWITCH_UHS18V)
			printf("CMD11 to switch to 1.8V mode failed, card requires power cycle.\n");
565 566
	}

567
	esdhc_write32(&regs->irqstat, -1);
568

569
	return err;
570 571
}

572
static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
573
{
574
	struct fsl_esdhc *regs = priv->esdhc_regs;
575 576
	int div = 1;
#ifdef ARCH_MXC
577 578 579 580
#ifdef CONFIG_MX53
	/* For i.MX53 eSDHCv3, SYSCTL.SDCLKFS may not be set to 0. */
	int pre_div = (regs == (struct fsl_esdhc *)MMC_SDHC3_BASE_ADDR) ? 2 : 1;
#else
581
	int pre_div = 1;
582
#endif
583 584 585 586
#else
	int pre_div = 2;
#endif
	int ddr_pre_div = mmc->ddr_mode ? 2 : 1;
P
Peng Fan 已提交
587
	int sdhc_clk = priv->sdhc_clk;
588 589
	uint clk;

590 591
	if (clock < mmc->cfg->f_min)
		clock = mmc->cfg->f_min;
592

593 594
	while (sdhc_clk / (16 * pre_div * ddr_pre_div) > clock && pre_div < 256)
		pre_div *= 2;
595

596 597
	while (sdhc_clk / (div * pre_div * ddr_pre_div) > clock && div < 16)
		div++;
598

599
	pre_div >>= 1;
600 601 602 603
	div -= 1;

	clk = (pre_div << 8) | (div << 4);

604
#ifdef CONFIG_FSL_USDHC
605
	esdhc_clrbits32(&regs->vendorspec, VENDORSPEC_CKEN);
606
#else
607
	esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
608
#endif
609 610

	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
611 612 613

	udelay(10000);

614
#ifdef CONFIG_FSL_USDHC
615
	esdhc_setbits32(&regs->vendorspec, VENDORSPEC_PEREN | VENDORSPEC_CKEN);
616 617 618
#else
	esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_CKEN);
#endif
619

620
	priv->clock = clock;
621 622
}

623
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
624
static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable)
625
{
P
Peng Fan 已提交
626
	struct fsl_esdhc *regs = priv->esdhc_regs;
627 628 629 630 631 632 633 634 635 636 637 638 639 640 641 642 643 644 645 646 647 648 649 650 651
	u32 value;
	u32 time_out;

	value = esdhc_read32(&regs->sysctl);

	if (enable)
		value |= SYSCTL_CKEN;
	else
		value &= ~SYSCTL_CKEN;

	esdhc_write32(&regs->sysctl, value);

	time_out = 20;
	value = PRSSTAT_SDSTB;
	while (!(esdhc_read32(&regs->prsstat) & value)) {
		if (time_out == 0) {
			printf("fsl_esdhc: Internal clock never stabilised.\n");
			break;
		}
		time_out--;
		mdelay(1);
	}
}
#endif

652 653 654 655 656 657 658 659 660 661 662 663 664
#ifdef MMC_SUPPORTS_TUNING
static int esdhc_change_pinstate(struct udevice *dev)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
	int ret;

	switch (priv->mode) {
	case UHS_SDR50:
	case UHS_DDR50:
		ret = pinctrl_select_state(dev, "state_100mhz");
		break;
	case UHS_SDR104:
	case MMC_HS_200:
P
Peng Fan 已提交
665
	case MMC_HS_400:
666 667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685 686 687 688 689 690 691 692
		ret = pinctrl_select_state(dev, "state_200mhz");
		break;
	default:
		ret = pinctrl_select_state(dev, "default");
		break;
	}

	if (ret)
		printf("%s %d error\n", __func__, priv->mode);

	return ret;
}

static void esdhc_reset_tuning(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;

	if (priv->flags & ESDHC_FLAG_USDHC) {
		if (priv->flags & ESDHC_FLAG_STD_TUNING) {
			esdhc_clrbits32(&regs->autoc12err,
					MIX_CTRL_SMPCLK_SEL |
					MIX_CTRL_EXE_TUNE);
		}
	}
}

P
Peng Fan 已提交
693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708 709 710 711 712 713 714 715 716 717 718 719
static void esdhc_set_strobe_dll(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;
	u32 val;

	if (priv->clock > ESDHC_STROBE_DLL_CLK_FREQ) {
		writel(ESDHC_STROBE_DLL_CTRL_RESET, &regs->strobe_dllctrl);

		/*
		 * enable strobe dll ctrl and adjust the delay target
		 * for the uSDHC loopback read clock
		 */
		val = ESDHC_STROBE_DLL_CTRL_ENABLE |
			(priv->strobe_dll_delay_target <<
			 ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_SHIFT);
		writel(val, &regs->strobe_dllctrl);
		/* wait 1us to make sure strobe dll status register stable */
		mdelay(1);
		val = readl(&regs->strobe_dllstat);
		if (!(val & ESDHC_STROBE_DLL_STS_REF_LOCK))
			pr_warn("HS400 strobe DLL status REF not lock!\n");
		if (!(val & ESDHC_STROBE_DLL_STS_SLV_LOCK))
			pr_warn("HS400 strobe DLL status SLV not lock!\n");
	}
}

720 721 722 723 724 725 726 727 728 729 730 731 732
static int esdhc_set_timing(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;
	u32 mixctrl;

	mixctrl = readl(&regs->mixctrl);
	mixctrl &= ~(MIX_CTRL_DDREN | MIX_CTRL_HS400_EN);

	switch (mmc->selected_mode) {
	case MMC_LEGACY:
	case SD_LEGACY:
		esdhc_reset_tuning(mmc);
P
Peng Fan 已提交
733 734 735 736 737 738
		writel(mixctrl, &regs->mixctrl);
		break;
	case MMC_HS_400:
		mixctrl |= MIX_CTRL_DDREN | MIX_CTRL_HS400_EN;
		writel(mixctrl, &regs->mixctrl);
		esdhc_set_strobe_dll(mmc);
739 740 741 742 743 744 745 746 747 748 749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765 766 767 768 769 770 771 772 773 774 775 776 777 778 779 780 781 782 783 784 785 786 787 788 789 790 791 792 793 794 795 796 797 798 799 800 801 802 803 804 805 806 807 808 809 810 811 812 813 814 815 816 817 818 819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838 839 840 841 842 843 844 845 846 847 848 849 850 851 852 853 854 855 856 857 858 859 860 861 862 863 864 865 866 867 868 869 870 871 872 873 874 875 876 877 878 879 880 881 882 883 884 885 886 887 888 889 890 891 892 893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914
		break;
	case MMC_HS:
	case MMC_HS_52:
	case MMC_HS_200:
	case SD_HS:
	case UHS_SDR12:
	case UHS_SDR25:
	case UHS_SDR50:
	case UHS_SDR104:
		writel(mixctrl, &regs->mixctrl);
		break;
	case UHS_DDR50:
	case MMC_DDR_52:
		mixctrl |= MIX_CTRL_DDREN;
		writel(mixctrl, &regs->mixctrl);
		break;
	default:
		printf("Not supported %d\n", mmc->selected_mode);
		return -EINVAL;
	}

	priv->mode = mmc->selected_mode;

	return esdhc_change_pinstate(mmc->dev);
}

static int esdhc_set_voltage(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(mmc->dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;
	int ret;

	priv->signal_voltage = mmc->signal_voltage;
	switch (mmc->signal_voltage) {
	case MMC_SIGNAL_VOLTAGE_330:
		if (priv->vs18_enable)
			return -EIO;
#ifdef CONFIG_DM_REGULATOR
		if (!IS_ERR_OR_NULL(priv->vqmmc_dev)) {
			ret = regulator_set_value(priv->vqmmc_dev, 3300000);
			if (ret) {
				printf("Setting to 3.3V error");
				return -EIO;
			}
			/* Wait for 5ms */
			mdelay(5);
		}
#endif

		esdhc_clrbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);
		if (!(esdhc_read32(&regs->vendorspec) &
		    ESDHC_VENDORSPEC_VSELECT))
			return 0;

		return -EAGAIN;
	case MMC_SIGNAL_VOLTAGE_180:
#ifdef CONFIG_DM_REGULATOR
		if (!IS_ERR_OR_NULL(priv->vqmmc_dev)) {
			ret = regulator_set_value(priv->vqmmc_dev, 1800000);
			if (ret) {
				printf("Setting to 1.8V error");
				return -EIO;
			}
		}
#endif
		esdhc_setbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);
		if (esdhc_read32(&regs->vendorspec) & ESDHC_VENDORSPEC_VSELECT)
			return 0;

		return -EAGAIN;
	case MMC_SIGNAL_VOLTAGE_120:
		return -ENOTSUPP;
	default:
		return 0;
	}
}

static void esdhc_stop_tuning(struct mmc *mmc)
{
	struct mmc_cmd cmd;

	cmd.cmdidx = MMC_CMD_STOP_TRANSMISSION;
	cmd.cmdarg = 0;
	cmd.resp_type = MMC_RSP_R1b;

	dm_mmc_send_cmd(mmc->dev, &cmd, NULL);
}

static int fsl_esdhc_execute_tuning(struct udevice *dev, uint32_t opcode)
{
	struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
	struct fsl_esdhc *regs = priv->esdhc_regs;
	struct mmc *mmc = &plat->mmc;
	u32 irqstaten = readl(&regs->irqstaten);
	u32 irqsigen = readl(&regs->irqsigen);
	int i, ret = -ETIMEDOUT;
	u32 val, mixctrl;

	/* clock tuning is not needed for upto 52MHz */
	if (mmc->clock <= 52000000)
		return 0;

	/* This is readw/writew SDHCI_HOST_CONTROL2 when tuning */
	if (priv->flags & ESDHC_FLAG_STD_TUNING) {
		val = readl(&regs->autoc12err);
		mixctrl = readl(&regs->mixctrl);
		val &= ~MIX_CTRL_SMPCLK_SEL;
		mixctrl &= ~(MIX_CTRL_FBCLK_SEL | MIX_CTRL_AUTO_TUNE_EN);

		val |= MIX_CTRL_EXE_TUNE;
		mixctrl |= MIX_CTRL_FBCLK_SEL | MIX_CTRL_AUTO_TUNE_EN;

		writel(val, &regs->autoc12err);
		writel(mixctrl, &regs->mixctrl);
	}

	/* sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE); */
	mixctrl = readl(&regs->mixctrl);
	mixctrl = MIX_CTRL_DTDSEL_READ | (mixctrl & ~MIX_CTRL_SDHCI_MASK);
	writel(mixctrl, &regs->mixctrl);

	writel(IRQSTATEN_BRR, &regs->irqstaten);
	writel(IRQSTATEN_BRR, &regs->irqsigen);

	/*
	 * Issue opcode repeatedly till Execute Tuning is set to 0 or the number
	 * of loops reaches 40 times.
	 */
	for (i = 0; i < MAX_TUNING_LOOP; i++) {
		u32 ctrl;

		if (opcode == MMC_CMD_SEND_TUNING_BLOCK_HS200) {
			if (mmc->bus_width == 8)
				writel(0x7080, &regs->blkattr);
			else if (mmc->bus_width == 4)
				writel(0x7040, &regs->blkattr);
		} else {
			writel(0x7040, &regs->blkattr);
		}

		/* sdhci_writew(host, SDHCI_TRNS_READ, SDHCI_TRANSFER_MODE) */
		val = readl(&regs->mixctrl);
		val = MIX_CTRL_DTDSEL_READ | (val & ~MIX_CTRL_SDHCI_MASK);
		writel(val, &regs->mixctrl);

		/* We are using STD tuning, no need to check return value */
		mmc_send_tuning(mmc, opcode, NULL);

		ctrl = readl(&regs->autoc12err);
		if ((!(ctrl & MIX_CTRL_EXE_TUNE)) &&
		    (ctrl & MIX_CTRL_SMPCLK_SEL)) {
			/*
			 * need to wait some time, make sure sd/mmc fininsh
			 * send out tuning data, otherwise, the sd/mmc can't
			 * response to any command when the card still out
			 * put the tuning data.
			 */
			mdelay(1);
			ret = 0;
			break;
		}

		/* Add 1ms delay for SD and eMMC */
		mdelay(1);
	}

	writel(irqstaten, &regs->irqstaten);
	writel(irqsigen, &regs->irqsigen);

	esdhc_stop_tuning(mmc);

	return ret;
}
#endif

915
static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
916
{
P
Peng Fan 已提交
917
	struct fsl_esdhc *regs = priv->esdhc_regs;
918
	int ret __maybe_unused;
919

920 921
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
	/* Select to use peripheral clock */
922
	esdhc_clock_control(priv, false);
923
	esdhc_setbits32(&regs->scr, ESDHCCTL_PCS);
924
	esdhc_clock_control(priv, true);
925
#endif
926
	/* Set the clock speed */
927 928 929 930 931 932 933 934 935 936 937 938 939 940 941 942 943 944 945 946 947 948 949 950 951 952 953 954 955 956 957 958 959 960 961
	if (priv->clock != mmc->clock)
		set_sysctl(priv, mmc, mmc->clock);

#ifdef MMC_SUPPORTS_TUNING
	if (mmc->clk_disable) {
#ifdef CONFIG_FSL_USDHC
		esdhc_clrbits32(&regs->vendorspec, VENDORSPEC_CKEN);
#else
		esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
#endif
	} else {
#ifdef CONFIG_FSL_USDHC
		esdhc_setbits32(&regs->vendorspec, VENDORSPEC_PEREN |
				VENDORSPEC_CKEN);
#else
		esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_CKEN);
#endif
	}

	if (priv->mode != mmc->selected_mode) {
		ret = esdhc_set_timing(mmc);
		if (ret) {
			printf("esdhc_set_timing error %d\n", ret);
			return ret;
		}
	}

	if (priv->signal_voltage != mmc->signal_voltage) {
		ret = esdhc_set_voltage(mmc);
		if (ret) {
			printf("esdhc_set_voltage error %d\n", ret);
			return ret;
		}
	}
#endif
962 963

	/* Set the bus width */
964
	esdhc_clrbits32(&regs->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
965 966

	if (mmc->bus_width == 4)
967
		esdhc_setbits32(&regs->proctl, PROCTL_DTW_4);
968
	else if (mmc->bus_width == 8)
969 970
		esdhc_setbits32(&regs->proctl, PROCTL_DTW_8);

971
	return 0;
972 973
}

974
static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
975
{
P
Peng Fan 已提交
976
	struct fsl_esdhc *regs = priv->esdhc_regs;
977
	ulong start;
978

979
	/* Reset the entire host controller */
980
	esdhc_setbits32(&regs->sysctl, SYSCTL_RSTA);
981 982

	/* Wait until the controller is available */
983 984 985 986 987
	start = get_timer(0);
	while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTA)) {
		if (get_timer(start) > 1000)
			return -ETIMEDOUT;
	}
988

989 990 991 992 993 994 995 996
#if defined(CONFIG_FSL_USDHC)
	/* RSTA doesn't reset MMC_BOOT register, so manually reset it */
	esdhc_write32(&regs->mmcboot, 0x0);
	/* Reset MIX_CTRL and CLK_TUNE_CTRL_STATUS regs to 0 */
	esdhc_write32(&regs->mixctrl, 0x0);
	esdhc_write32(&regs->clktunectrlstatus, 0x0);

	/* Put VEND_SPEC to default value */
997 998 999 1000 1001
	if (priv->vs18_enable)
		esdhc_write32(&regs->vendorspec, (VENDORSPEC_INIT |
			      ESDHC_VENDORSPEC_VSELECT));
	else
		esdhc_write32(&regs->vendorspec, VENDORSPEC_INIT);
1002 1003 1004 1005 1006

	/* Disable DLL_CTRL delay line */
	esdhc_write32(&regs->dllctrl, 0x0);
#endif

1007
#ifndef ARCH_MXC
1008
	/* Enable cache snooping */
1009 1010
	esdhc_write32(&regs->scr, 0x00000040);
#endif
1011

1012
#ifndef CONFIG_FSL_USDHC
1013
	esdhc_setbits32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
1014 1015
#else
	esdhc_setbits32(&regs->vendorspec, VENDORSPEC_HCKEN | VENDORSPEC_IPGEN);
1016
#endif
1017 1018

	/* Set the initial clock speed */
1019
	mmc_set_clock(mmc, 400000, MMC_CLK_ENABLE);
1020 1021

	/* Disable the BRR and BWR bits in IRQSTAT */
1022
	esdhc_clrbits32(&regs->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
1023 1024

	/* Put the PROCTL reg back to the default */
1025
	esdhc_write32(&regs->proctl, PROCTL_INIT);
1026

1027 1028
	/* Set timout to the maximum value */
	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
1029

1030 1031
	return 0;
}
1032

1033
static int esdhc_getcd_common(struct fsl_esdhc_priv *priv)
1034
{
P
Peng Fan 已提交
1035
	struct fsl_esdhc *regs = priv->esdhc_regs;
1036 1037
	int timeout = 1000;

1038 1039 1040 1041
#ifdef CONFIG_ESDHC_DETECT_QUIRK
	if (CONFIG_ESDHC_DETECT_QUIRK)
		return 1;
#endif
P
Peng Fan 已提交
1042

1043
#if CONFIG_IS_ENABLED(DM_MMC)
P
Peng Fan 已提交
1044 1045
	if (priv->non_removable)
		return 1;
1046
#ifdef CONFIG_DM_GPIO
P
Peng Fan 已提交
1047 1048
	if (dm_gpio_is_valid(&priv->cd_gpio))
		return dm_gpio_get_value(&priv->cd_gpio);
1049
#endif
P
Peng Fan 已提交
1050 1051
#endif

1052 1053
	while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_CINS) && --timeout)
		udelay(1000);
1054

1055
	return timeout > 0;
1056 1057
}

1058
static int esdhc_reset(struct fsl_esdhc *regs)
1059
{
1060
	ulong start;
1061 1062

	/* reset the controller */
1063
	esdhc_setbits32(&regs->sysctl, SYSCTL_RSTA);
1064 1065

	/* hardware clears the bit when it is done */
1066 1067 1068 1069 1070 1071 1072 1073 1074
	start = get_timer(0);
	while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTA)) {
		if (get_timer(start) > 100) {
			printf("MMC/SD: Reset never completed.\n");
			return -ETIMEDOUT;
		}
	}

	return 0;
1075 1076
}

S
Simon Glass 已提交
1077
#if !CONFIG_IS_ENABLED(DM_MMC)
1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106
static int esdhc_getcd(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = mmc->priv;

	return esdhc_getcd_common(priv);
}

static int esdhc_init(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = mmc->priv;

	return esdhc_init_common(priv, mmc);
}

static int esdhc_send_cmd(struct mmc *mmc, struct mmc_cmd *cmd,
			  struct mmc_data *data)
{
	struct fsl_esdhc_priv *priv = mmc->priv;

	return esdhc_send_cmd_common(priv, mmc, cmd, data);
}

static int esdhc_set_ios(struct mmc *mmc)
{
	struct fsl_esdhc_priv *priv = mmc->priv;

	return esdhc_set_ios_common(priv, mmc);
}

1107
static const struct mmc_ops esdhc_ops = {
1108 1109
	.getcd		= esdhc_getcd,
	.init		= esdhc_init,
1110 1111 1112
	.send_cmd	= esdhc_send_cmd,
	.set_ios	= esdhc_set_ios,
};
1113
#endif
1114

1115 1116
static int fsl_esdhc_init(struct fsl_esdhc_priv *priv,
			  struct fsl_esdhc_plat *plat)
1117
{
1118
	struct mmc_config *cfg;
1119
	struct fsl_esdhc *regs;
1120
	u32 caps, voltage_caps;
1121
	int ret;
1122

P
Peng Fan 已提交
1123 1124
	if (!priv)
		return -EINVAL;
1125

P
Peng Fan 已提交
1126
	regs = priv->esdhc_regs;
1127

1128
	/* First reset the eSDHC controller */
1129 1130 1131
	ret = esdhc_reset(regs);
	if (ret)
		return ret;
1132

1133
#ifndef CONFIG_FSL_USDHC
1134 1135
	esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN
				| SYSCTL_IPGEN | SYSCTL_CKEN);
1136 1137 1138 1139
	/* Clearing tuning bits in case ROM has set it already */
	esdhc_write32(&regs->mixctrl, 0);
	esdhc_write32(&regs->autoc12err, 0);
	esdhc_write32(&regs->clktunectrlstatus, 0);
1140 1141 1142
#else
	esdhc_setbits32(&regs->vendorspec, VENDORSPEC_PEREN |
			VENDORSPEC_HCKEN | VENDORSPEC_IPGEN | VENDORSPEC_CKEN);
1143
#endif
1144

1145 1146 1147
	if (priv->vs18_enable)
		esdhc_setbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);

1148
	writel(SDHCI_IRQ_EN_BITS, &regs->irqstaten);
1149
	cfg = &plat->cfg;
1150
#ifndef CONFIG_DM_MMC
1151
	memset(cfg, '\0', sizeof(*cfg));
1152
#endif
1153

1154
	voltage_caps = 0;
1155
	caps = esdhc_read32(&regs->hostcapblt);
1156 1157 1158 1159 1160

#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135
	caps = caps & ~(ESDHC_HOSTCAPBLT_SRS |
			ESDHC_HOSTCAPBLT_VS18 | ESDHC_HOSTCAPBLT_VS30);
#endif
1161 1162 1163 1164 1165 1166

/* T4240 host controller capabilities register should have VS33 bit */
#ifdef CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33
	caps = caps | ESDHC_HOSTCAPBLT_VS33;
#endif

1167
	if (caps & ESDHC_HOSTCAPBLT_VS18)
1168
		voltage_caps |= MMC_VDD_165_195;
1169
	if (caps & ESDHC_HOSTCAPBLT_VS30)
1170
		voltage_caps |= MMC_VDD_29_30 | MMC_VDD_30_31;
1171
	if (caps & ESDHC_HOSTCAPBLT_VS33)
1172 1173
		voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34;

1174
	cfg->name = "FSL_SDHC";
S
Simon Glass 已提交
1175
#if !CONFIG_IS_ENABLED(DM_MMC)
1176
	cfg->ops = &esdhc_ops;
1177
#endif
1178
#ifdef CONFIG_SYS_SD_VOLTAGE
1179
	cfg->voltages = CONFIG_SYS_SD_VOLTAGE;
1180
#else
1181
	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
1182
#endif
1183
	if ((cfg->voltages & voltage_caps) == 0) {
1184 1185 1186
		printf("voltage not supported by controller\n");
		return -1;
	}
1187

P
Peng Fan 已提交
1188
	if (priv->bus_width == 8)
1189
		cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
P
Peng Fan 已提交
1190
	else if (priv->bus_width == 4)
1191
		cfg->host_caps = MMC_MODE_4BIT;
P
Peng Fan 已提交
1192

1193
	cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
1194
#ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
1195
	cfg->host_caps |= MMC_MODE_DDR_52MHz;
1196
#endif
1197

P
Peng Fan 已提交
1198 1199
	if (priv->bus_width > 0) {
		if (priv->bus_width < 8)
1200
			cfg->host_caps &= ~MMC_MODE_8BIT;
P
Peng Fan 已提交
1201
		if (priv->bus_width < 4)
1202
			cfg->host_caps &= ~MMC_MODE_4BIT;
1203 1204
	}

1205
	if (caps & ESDHC_HOSTCAPBLT_HSS)
1206
		cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
1207

1208 1209
#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK
	if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK)
1210
		cfg->host_caps &= ~MMC_MODE_8BIT;
1211 1212
#endif

1213 1214
	cfg->host_caps |= priv->caps;

1215
	cfg->f_min = 400000;
1216
	cfg->f_max = min(priv->sdhc_clk, (u32)200000000);
1217

1218
	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
1219

1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231 1232 1233
	writel(0, &regs->dllctrl);
	if (priv->flags & ESDHC_FLAG_USDHC) {
		if (priv->flags & ESDHC_FLAG_STD_TUNING) {
			u32 val = readl(&regs->tuning_ctrl);

			val |= ESDHC_STD_TUNING_EN;
			val &= ~ESDHC_TUNING_START_TAP_MASK;
			val |= priv->tuning_start_tap;
			val &= ~ESDHC_TUNING_STEP_MASK;
			val |= (priv->tuning_step) << ESDHC_TUNING_STEP_SHIFT;
			writel(val, &regs->tuning_ctrl);
		}
	}

P
Peng Fan 已提交
1234 1235 1236
	return 0;
}

1237
#if !CONFIG_IS_ENABLED(DM_MMC)
1238 1239 1240 1241 1242 1243 1244 1245 1246 1247
static int fsl_esdhc_cfg_to_priv(struct fsl_esdhc_cfg *cfg,
				 struct fsl_esdhc_priv *priv)
{
	if (!cfg || !priv)
		return -EINVAL;

	priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base);
	priv->bus_width = cfg->max_bus_width;
	priv->sdhc_clk = cfg->sdhc_clk;
	priv->wp_enable  = cfg->wp_enable;
1248
	priv->vs18_enable  = cfg->vs18_enable;
1249 1250 1251 1252

	return 0;
};

P
Peng Fan 已提交
1253 1254
int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
{
1255
	struct fsl_esdhc_plat *plat;
P
Peng Fan 已提交
1256
	struct fsl_esdhc_priv *priv;
1257
	struct mmc *mmc;
P
Peng Fan 已提交
1258 1259 1260 1261 1262 1263 1264 1265
	int ret;

	if (!cfg)
		return -EINVAL;

	priv = calloc(sizeof(struct fsl_esdhc_priv), 1);
	if (!priv)
		return -ENOMEM;
1266 1267 1268 1269 1270
	plat = calloc(sizeof(struct fsl_esdhc_plat), 1);
	if (!plat) {
		free(priv);
		return -ENOMEM;
	}
P
Peng Fan 已提交
1271 1272 1273 1274

	ret = fsl_esdhc_cfg_to_priv(cfg, priv);
	if (ret) {
		debug("%s xlate failure\n", __func__);
1275
		free(plat);
P
Peng Fan 已提交
1276 1277 1278 1279
		free(priv);
		return ret;
	}

1280
	ret = fsl_esdhc_init(priv, plat);
P
Peng Fan 已提交
1281 1282
	if (ret) {
		debug("%s init failure\n", __func__);
1283
		free(plat);
P
Peng Fan 已提交
1284 1285 1286 1287
		free(priv);
		return ret;
	}

1288 1289 1290 1291 1292 1293
	mmc = mmc_create(&plat->cfg, priv);
	if (!mmc)
		return -EIO;

	priv->mmc = mmc;

1294 1295 1296 1297 1298
	return 0;
}

int fsl_esdhc_mmc_init(bd_t *bis)
{
1299 1300
	struct fsl_esdhc_cfg *cfg;

F
Fabio Estevam 已提交
1301
	cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1);
1302
	cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
1303
	cfg->sdhc_clk = gd->arch.sdhc_clk;
1304
	return fsl_esdhc_initialize(bis, cfg);
1305
}
1306
#endif
1307

1308 1309 1310 1311 1312 1313 1314 1315 1316 1317 1318
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
void mmc_adapter_card_type_ident(void)
{
	u8 card_id;
	u8 value;

	card_id = QIXIS_READ(present) & QIXIS_SDID_MASK;
	gd->arch.sdhc_adapter = card_id;

	switch (card_id) {
	case QIXIS_ESDHC_ADAPTER_TYPE_EMMC45:
1319 1320 1321
		value = QIXIS_READ(brdcfg[5]);
		value |= (QIXIS_DAT4 | QIXIS_DAT5_6_7);
		QIXIS_WRITE(brdcfg[5], value);
1322 1323
		break;
	case QIXIS_ESDHC_ADAPTER_TYPE_SDMMC_LEGACY:
1324 1325 1326
		value = QIXIS_READ(pwr_ctl[1]);
		value |= QIXIS_EVDD_BY_SDHC_VS;
		QIXIS_WRITE(pwr_ctl[1], value);
1327 1328 1329 1330 1331 1332 1333 1334 1335 1336 1337 1338 1339 1340 1341 1342 1343 1344 1345 1346
		break;
	case QIXIS_ESDHC_ADAPTER_TYPE_EMMC44:
		value = QIXIS_READ(brdcfg[5]);
		value |= (QIXIS_SDCLKIN | QIXIS_SDCLKOUT);
		QIXIS_WRITE(brdcfg[5], value);
		break;
	case QIXIS_ESDHC_ADAPTER_TYPE_RSV:
		break;
	case QIXIS_ESDHC_ADAPTER_TYPE_MMC:
		break;
	case QIXIS_ESDHC_ADAPTER_TYPE_SD:
		break;
	case QIXIS_ESDHC_NO_ADAPTER:
		break;
	default:
		break;
	}
}
#endif

1347
#ifdef CONFIG_OF_LIBFDT
1348
__weak int esdhc_status_fixup(void *blob, const char *compat)
1349
{
1350
#ifdef CONFIG_FSL_ESDHC_PIN_MUX
1351
	if (!hwconfig("esdhc")) {
1352
		do_fixup_by_compat(blob, compat, "status", "disabled",
1353 1354
				sizeof("disabled"), 1);
		return 1;
1355
	}
1356
#endif
1357 1358 1359 1360 1361 1362 1363 1364 1365
	return 0;
}

void fdt_fixup_esdhc(void *blob, bd_t *bd)
{
	const char *compat = "fsl,esdhc";

	if (esdhc_status_fixup(blob, compat))
		return;
1366

1367 1368 1369 1370
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
	do_fixup_by_compat_u32(blob, compat, "peripheral-frequency",
			       gd->arch.sdhc_clk, 1);
#else
1371
	do_fixup_by_compat_u32(blob, compat, "clock-frequency",
1372
			       gd->arch.sdhc_clk, 1);
1373
#endif
1374 1375 1376 1377
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
	do_fixup_by_compat_u32(blob, compat, "adapter-type",
			       (u32)(gd->arch.sdhc_adapter), 1);
#endif
1378
}
1379
#endif
P
Peng Fan 已提交
1380

1381
#if CONFIG_IS_ENABLED(DM_MMC)
P
Peng Fan 已提交
1382
#include <asm/arch/clock.h>
P
Peng Fan 已提交
1383 1384 1385 1386
__weak void init_clk_usdhc(u32 index)
{
}

P
Peng Fan 已提交
1387 1388 1389
static int fsl_esdhc_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
1390
	struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
P
Peng Fan 已提交
1391
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
1392 1393 1394 1395
	const void *fdt = gd->fdt_blob;
	int node = dev_of_offset(dev);
	struct esdhc_soc_data *data =
		(struct esdhc_soc_data *)dev_get_driver_data(dev);
1396
#ifdef CONFIG_DM_REGULATOR
1397
	struct udevice *vqmmc_dev;
1398
#endif
P
Peng Fan 已提交
1399 1400
	fdt_addr_t addr;
	unsigned int val;
1401
	struct mmc *mmc;
P
Peng Fan 已提交
1402 1403
	int ret;

1404
	addr = dev_read_addr(dev);
P
Peng Fan 已提交
1405 1406 1407 1408 1409
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	priv->esdhc_regs = (struct fsl_esdhc *)addr;
	priv->dev = dev;
1410 1411 1412 1413 1414
	priv->mode = -1;
	if (data) {
		priv->flags = data->flags;
		priv->caps = data->caps;
	}
P
Peng Fan 已提交
1415

1416
	val = dev_read_u32_default(dev, "bus-width", -1);
P
Peng Fan 已提交
1417 1418 1419 1420 1421 1422 1423
	if (val == 8)
		priv->bus_width = 8;
	else if (val == 4)
		priv->bus_width = 4;
	else
		priv->bus_width = 1;

1424 1425 1426 1427 1428 1429 1430 1431 1432
	val = fdtdec_get_int(fdt, node, "fsl,tuning-step", 1);
	priv->tuning_step = val;
	val = fdtdec_get_int(fdt, node, "fsl,tuning-start-tap",
			     ESDHC_TUNING_START_TAP_DEFAULT);
	priv->tuning_start_tap = val;
	val = fdtdec_get_int(fdt, node, "fsl,strobe-dll-delay-target",
			     ESDHC_STROBE_DLL_CTRL_SLV_DLY_TARGET_DEFAULT);
	priv->strobe_dll_delay_target = val;

1433
	if (dev_read_bool(dev, "non-removable")) {
P
Peng Fan 已提交
1434 1435 1436
		priv->non_removable = 1;
	 } else {
		priv->non_removable = 0;
1437
#ifdef CONFIG_DM_GPIO
1438 1439
		gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
				     GPIOD_IS_IN);
1440
#endif
P
Peng Fan 已提交
1441 1442
	}

P
Peng Fan 已提交
1443 1444
	priv->wp_enable = 1;

1445
#ifdef CONFIG_DM_GPIO
1446 1447
	ret = gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio,
				   GPIOD_IS_IN);
P
Peng Fan 已提交
1448 1449
	if (ret)
		priv->wp_enable = 0;
1450
#endif
1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461 1462 1463 1464 1465 1466 1467 1468 1469 1470 1471 1472 1473

	priv->vs18_enable = 0;

#ifdef CONFIG_DM_REGULATOR
	/*
	 * If emmc I/O has a fixed voltage at 1.8V, this must be provided,
	 * otherwise, emmc will work abnormally.
	 */
	ret = device_get_supply_regulator(dev, "vqmmc-supply", &vqmmc_dev);
	if (ret) {
		dev_dbg(dev, "no vqmmc-supply\n");
	} else {
		ret = regulator_set_enable(vqmmc_dev, true);
		if (ret) {
			dev_err(dev, "fail to enable vqmmc-supply\n");
			return ret;
		}

		if (regulator_get_value(vqmmc_dev) == 1800000)
			priv->vs18_enable = 1;
	}
#endif

1474
	if (fdt_get_property(fdt, node, "no-1-8-v", NULL))
P
Peng Fan 已提交
1475
		priv->caps &= ~(UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_HS400);
1476

P
Peng Fan 已提交
1477 1478 1479 1480 1481 1482 1483 1484 1485 1486 1487 1488 1489 1490 1491 1492 1493 1494 1495
	/*
	 * TODO:
	 * Because lack of clk driver, if SDHC clk is not enabled,
	 * need to enable it first before this driver is invoked.
	 *
	 * we use MXC_ESDHC_CLK to get clk freq.
	 * If one would like to make this function work,
	 * the aliases should be provided in dts as this:
	 *
	 *  aliases {
	 *	mmc0 = &usdhc1;
	 *	mmc1 = &usdhc2;
	 *	mmc2 = &usdhc3;
	 *	mmc3 = &usdhc4;
	 *	};
	 * Then if your board only supports mmc2 and mmc3, but we can
	 * correctly get the seq as 2 and 3, then let mxc_get_clock
	 * work as expected.
	 */
P
Peng Fan 已提交
1496 1497 1498

	init_clk_usdhc(dev->seq);

P
Peng Fan 已提交
1499 1500 1501 1502 1503 1504
	priv->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK + dev->seq);
	if (priv->sdhc_clk <= 0) {
		dev_err(dev, "Unable to get clk for %s\n", dev->name);
		return -EINVAL;
	}

1505
	ret = fsl_esdhc_init(priv, plat);
P
Peng Fan 已提交
1506 1507 1508 1509 1510
	if (ret) {
		dev_err(dev, "fsl_esdhc_init failure\n");
		return ret;
	}

1511 1512 1513 1514
	mmc = &plat->mmc;
	mmc->cfg = &plat->cfg;
	mmc->dev = dev;
	upriv->mmc = mmc;
P
Peng Fan 已提交
1515

1516
	return esdhc_init_common(priv, mmc);
P
Peng Fan 已提交
1517 1518
}

S
Simon Glass 已提交
1519
#if CONFIG_IS_ENABLED(DM_MMC)
1520 1521 1522 1523 1524 1525 1526 1527 1528 1529 1530 1531 1532 1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544 1545 1546 1547 1548
static int fsl_esdhc_get_cd(struct udevice *dev)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);

	return true;
	return esdhc_getcd_common(priv);
}

static int fsl_esdhc_send_cmd(struct udevice *dev, struct mmc_cmd *cmd,
			      struct mmc_data *data)
{
	struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);

	return esdhc_send_cmd_common(priv, &plat->mmc, cmd, data);
}

static int fsl_esdhc_set_ios(struct udevice *dev)
{
	struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);

	return esdhc_set_ios_common(priv, &plat->mmc);
}

static const struct dm_mmc_ops fsl_esdhc_ops = {
	.get_cd		= fsl_esdhc_get_cd,
	.send_cmd	= fsl_esdhc_send_cmd,
	.set_ios	= fsl_esdhc_set_ios,
1549 1550 1551
#ifdef MMC_SUPPORTS_TUNING
	.execute_tuning	= fsl_esdhc_execute_tuning,
#endif
1552 1553 1554
};
#endif

1555 1556 1557 1558 1559 1560 1561 1562
static struct esdhc_soc_data usdhc_imx7d_data = {
	.flags = ESDHC_FLAG_USDHC | ESDHC_FLAG_STD_TUNING
			| ESDHC_FLAG_HAVE_CAP1 | ESDHC_FLAG_HS200
			| ESDHC_FLAG_HS400,
	.caps = UHS_CAPS | MMC_MODE_HS200 | MMC_MODE_DDR_52MHz |
		MMC_MODE_HS_52MHz | MMC_MODE_HS,
};

P
Peng Fan 已提交
1563 1564 1565 1566 1567
static const struct udevice_id fsl_esdhc_ids[] = {
	{ .compatible = "fsl,imx6ul-usdhc", },
	{ .compatible = "fsl,imx6sx-usdhc", },
	{ .compatible = "fsl,imx6sl-usdhc", },
	{ .compatible = "fsl,imx6q-usdhc", },
1568
	{ .compatible = "fsl,imx7d-usdhc", .data = (ulong)&usdhc_imx7d_data,},
P
Peng Fan 已提交
1569
	{ .compatible = "fsl,imx7ulp-usdhc", },
1570
	{ .compatible = "fsl,esdhc", },
P
Peng Fan 已提交
1571 1572 1573
	{ /* sentinel */ }
};

1574 1575 1576 1577 1578 1579 1580 1581 1582
#if CONFIG_IS_ENABLED(BLK)
static int fsl_esdhc_bind(struct udevice *dev)
{
	struct fsl_esdhc_plat *plat = dev_get_platdata(dev);

	return mmc_bind(dev, &plat->mmc, &plat->cfg);
}
#endif

P
Peng Fan 已提交
1583 1584 1585 1586
U_BOOT_DRIVER(fsl_esdhc) = {
	.name	= "fsl-esdhc-mmc",
	.id	= UCLASS_MMC,
	.of_match = fsl_esdhc_ids,
1587 1588 1589 1590
	.ops	= &fsl_esdhc_ops,
#if CONFIG_IS_ENABLED(BLK)
	.bind	= fsl_esdhc_bind,
#endif
P
Peng Fan 已提交
1591
	.probe	= fsl_esdhc_probe,
1592
	.platdata_auto_alloc_size = sizeof(struct fsl_esdhc_plat),
P
Peng Fan 已提交
1593 1594 1595
	.priv_auto_alloc_size = sizeof(struct fsl_esdhc_priv),
};
#endif