fsl_esdhc.c 38.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 665 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 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 720 721 722 723 724 725 726 727 728 729 730 731 732 733 734 735 736 737 738 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
#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:
		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);
		}
	}
}

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);
		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

881
static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
882
{
P
Peng Fan 已提交
883
	struct fsl_esdhc *regs = priv->esdhc_regs;
884
	int ret __maybe_unused;
885

886 887
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
	/* Select to use peripheral clock */
888
	esdhc_clock_control(priv, false);
889
	esdhc_setbits32(&regs->scr, ESDHCCTL_PCS);
890
	esdhc_clock_control(priv, true);
891
#endif
892
	/* Set the clock speed */
893 894 895 896 897 898 899 900 901 902 903 904 905 906 907 908 909 910 911 912 913 914 915 916 917 918 919 920 921 922 923 924 925 926 927
	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
928 929

	/* Set the bus width */
930
	esdhc_clrbits32(&regs->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
931 932

	if (mmc->bus_width == 4)
933
		esdhc_setbits32(&regs->proctl, PROCTL_DTW_4);
934
	else if (mmc->bus_width == 8)
935 936
		esdhc_setbits32(&regs->proctl, PROCTL_DTW_8);

937
	return 0;
938 939
}

940
static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
941
{
P
Peng Fan 已提交
942
	struct fsl_esdhc *regs = priv->esdhc_regs;
943
	ulong start;
944

945
	/* Reset the entire host controller */
946
	esdhc_setbits32(&regs->sysctl, SYSCTL_RSTA);
947 948

	/* Wait until the controller is available */
949 950 951 952 953
	start = get_timer(0);
	while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTA)) {
		if (get_timer(start) > 1000)
			return -ETIMEDOUT;
	}
954

955 956 957 958 959 960 961 962
#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 */
963 964 965 966 967
	if (priv->vs18_enable)
		esdhc_write32(&regs->vendorspec, (VENDORSPEC_INIT |
			      ESDHC_VENDORSPEC_VSELECT));
	else
		esdhc_write32(&regs->vendorspec, VENDORSPEC_INIT);
968 969 970 971 972

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

973
#ifndef ARCH_MXC
974
	/* Enable cache snooping */
975 976
	esdhc_write32(&regs->scr, 0x00000040);
#endif
977

978
#ifndef CONFIG_FSL_USDHC
979
	esdhc_setbits32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
980 981
#else
	esdhc_setbits32(&regs->vendorspec, VENDORSPEC_HCKEN | VENDORSPEC_IPGEN);
982
#endif
983 984

	/* Set the initial clock speed */
985
	mmc_set_clock(mmc, 400000, false);
986 987

	/* Disable the BRR and BWR bits in IRQSTAT */
988
	esdhc_clrbits32(&regs->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
989 990

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

993 994
	/* Set timout to the maximum value */
	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
995

996 997
	return 0;
}
998

999
static int esdhc_getcd_common(struct fsl_esdhc_priv *priv)
1000
{
P
Peng Fan 已提交
1001
	struct fsl_esdhc *regs = priv->esdhc_regs;
1002 1003
	int timeout = 1000;

1004 1005 1006 1007
#ifdef CONFIG_ESDHC_DETECT_QUIRK
	if (CONFIG_ESDHC_DETECT_QUIRK)
		return 1;
#endif
P
Peng Fan 已提交
1008

1009
#if CONFIG_IS_ENABLED(DM_MMC)
P
Peng Fan 已提交
1010 1011
	if (priv->non_removable)
		return 1;
1012
#ifdef CONFIG_DM_GPIO
P
Peng Fan 已提交
1013 1014
	if (dm_gpio_is_valid(&priv->cd_gpio))
		return dm_gpio_get_value(&priv->cd_gpio);
1015
#endif
P
Peng Fan 已提交
1016 1017
#endif

1018 1019
	while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_CINS) && --timeout)
		udelay(1000);
1020

1021
	return timeout > 0;
1022 1023
}

1024
static int esdhc_reset(struct fsl_esdhc *regs)
1025
{
1026
	ulong start;
1027 1028

	/* reset the controller */
1029
	esdhc_setbits32(&regs->sysctl, SYSCTL_RSTA);
1030 1031

	/* hardware clears the bit when it is done */
1032 1033 1034 1035 1036 1037 1038 1039 1040
	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;
1041 1042
}

S
Simon Glass 已提交
1043
#if !CONFIG_IS_ENABLED(DM_MMC)
1044 1045 1046 1047 1048 1049 1050 1051 1052 1053 1054 1055 1056 1057 1058 1059 1060 1061 1062 1063 1064 1065 1066 1067 1068 1069 1070 1071 1072
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);
}

1073
static const struct mmc_ops esdhc_ops = {
1074 1075
	.getcd		= esdhc_getcd,
	.init		= esdhc_init,
1076 1077 1078
	.send_cmd	= esdhc_send_cmd,
	.set_ios	= esdhc_set_ios,
};
1079
#endif
1080

1081 1082
static int fsl_esdhc_init(struct fsl_esdhc_priv *priv,
			  struct fsl_esdhc_plat *plat)
1083
{
1084
	struct mmc_config *cfg;
1085
	struct fsl_esdhc *regs;
1086
	u32 caps, voltage_caps;
1087
	int ret;
1088

P
Peng Fan 已提交
1089 1090
	if (!priv)
		return -EINVAL;
1091

P
Peng Fan 已提交
1092
	regs = priv->esdhc_regs;
1093

1094
	/* First reset the eSDHC controller */
1095 1096 1097
	ret = esdhc_reset(regs);
	if (ret)
		return ret;
1098

1099
#ifndef CONFIG_FSL_USDHC
1100 1101
	esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_HCKEN
				| SYSCTL_IPGEN | SYSCTL_CKEN);
1102 1103 1104 1105
	/* 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);
1106 1107 1108
#else
	esdhc_setbits32(&regs->vendorspec, VENDORSPEC_PEREN |
			VENDORSPEC_HCKEN | VENDORSPEC_IPGEN | VENDORSPEC_CKEN);
1109
#endif
1110

1111 1112 1113
	if (priv->vs18_enable)
		esdhc_setbits32(&regs->vendorspec, ESDHC_VENDORSPEC_VSELECT);

1114
	writel(SDHCI_IRQ_EN_BITS, &regs->irqstaten);
1115
	cfg = &plat->cfg;
1116
#ifndef CONFIG_DM_MMC
1117
	memset(cfg, '\0', sizeof(*cfg));
1118
#endif
1119

1120
	voltage_caps = 0;
1121
	caps = esdhc_read32(&regs->hostcapblt);
1122 1123 1124 1125 1126

#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135
	caps = caps & ~(ESDHC_HOSTCAPBLT_SRS |
			ESDHC_HOSTCAPBLT_VS18 | ESDHC_HOSTCAPBLT_VS30);
#endif
1127 1128 1129 1130 1131 1132

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

1133
	if (caps & ESDHC_HOSTCAPBLT_VS18)
1134
		voltage_caps |= MMC_VDD_165_195;
1135
	if (caps & ESDHC_HOSTCAPBLT_VS30)
1136
		voltage_caps |= MMC_VDD_29_30 | MMC_VDD_30_31;
1137
	if (caps & ESDHC_HOSTCAPBLT_VS33)
1138 1139
		voltage_caps |= MMC_VDD_32_33 | MMC_VDD_33_34;

1140
	cfg->name = "FSL_SDHC";
S
Simon Glass 已提交
1141
#if !CONFIG_IS_ENABLED(DM_MMC)
1142
	cfg->ops = &esdhc_ops;
1143
#endif
1144
#ifdef CONFIG_SYS_SD_VOLTAGE
1145
	cfg->voltages = CONFIG_SYS_SD_VOLTAGE;
1146
#else
1147
	cfg->voltages = MMC_VDD_32_33 | MMC_VDD_33_34;
1148
#endif
1149
	if ((cfg->voltages & voltage_caps) == 0) {
1150 1151 1152
		printf("voltage not supported by controller\n");
		return -1;
	}
1153

P
Peng Fan 已提交
1154
	if (priv->bus_width == 8)
1155
		cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
P
Peng Fan 已提交
1156
	else if (priv->bus_width == 4)
1157
		cfg->host_caps = MMC_MODE_4BIT;
P
Peng Fan 已提交
1158

1159
	cfg->host_caps = MMC_MODE_4BIT | MMC_MODE_8BIT;
1160
#ifdef CONFIG_SYS_FSL_ESDHC_HAS_DDR_MODE
1161
	cfg->host_caps |= MMC_MODE_DDR_52MHz;
1162
#endif
1163

P
Peng Fan 已提交
1164 1165
	if (priv->bus_width > 0) {
		if (priv->bus_width < 8)
1166
			cfg->host_caps &= ~MMC_MODE_8BIT;
P
Peng Fan 已提交
1167
		if (priv->bus_width < 4)
1168
			cfg->host_caps &= ~MMC_MODE_4BIT;
1169 1170
	}

1171
	if (caps & ESDHC_HOSTCAPBLT_HSS)
1172
		cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
1173

1174 1175
#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK
	if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK)
1176
		cfg->host_caps &= ~MMC_MODE_8BIT;
1177 1178
#endif

1179 1180
	cfg->host_caps |= priv->caps;

1181
	cfg->f_min = 400000;
1182
	cfg->f_max = min(priv->sdhc_clk, (u32)200000000);
1183

1184
	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
1185

1186 1187 1188 1189 1190 1191 1192 1193 1194 1195 1196 1197 1198 1199
	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 已提交
1200 1201 1202
	return 0;
}

1203
#if !CONFIG_IS_ENABLED(DM_MMC)
1204 1205 1206 1207 1208 1209 1210 1211 1212 1213
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;
1214
	priv->vs18_enable  = cfg->vs18_enable;
1215 1216 1217 1218

	return 0;
};

P
Peng Fan 已提交
1219 1220
int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
{
1221
	struct fsl_esdhc_plat *plat;
P
Peng Fan 已提交
1222
	struct fsl_esdhc_priv *priv;
1223
	struct mmc *mmc;
P
Peng Fan 已提交
1224 1225 1226 1227 1228 1229 1230 1231
	int ret;

	if (!cfg)
		return -EINVAL;

	priv = calloc(sizeof(struct fsl_esdhc_priv), 1);
	if (!priv)
		return -ENOMEM;
1232 1233 1234 1235 1236
	plat = calloc(sizeof(struct fsl_esdhc_plat), 1);
	if (!plat) {
		free(priv);
		return -ENOMEM;
	}
P
Peng Fan 已提交
1237 1238 1239 1240

	ret = fsl_esdhc_cfg_to_priv(cfg, priv);
	if (ret) {
		debug("%s xlate failure\n", __func__);
1241
		free(plat);
P
Peng Fan 已提交
1242 1243 1244 1245
		free(priv);
		return ret;
	}

1246
	ret = fsl_esdhc_init(priv, plat);
P
Peng Fan 已提交
1247 1248
	if (ret) {
		debug("%s init failure\n", __func__);
1249
		free(plat);
P
Peng Fan 已提交
1250 1251 1252 1253
		free(priv);
		return ret;
	}

1254 1255 1256 1257 1258 1259
	mmc = mmc_create(&plat->cfg, priv);
	if (!mmc)
		return -EIO;

	priv->mmc = mmc;

1260 1261 1262 1263 1264
	return 0;
}

int fsl_esdhc_mmc_init(bd_t *bis)
{
1265 1266
	struct fsl_esdhc_cfg *cfg;

F
Fabio Estevam 已提交
1267
	cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1);
1268
	cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
1269
	cfg->sdhc_clk = gd->arch.sdhc_clk;
1270
	return fsl_esdhc_initialize(bis, cfg);
1271
}
1272
#endif
1273

1274 1275 1276 1277 1278 1279 1280 1281 1282 1283 1284
#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:
1285 1286 1287
		value = QIXIS_READ(brdcfg[5]);
		value |= (QIXIS_DAT4 | QIXIS_DAT5_6_7);
		QIXIS_WRITE(brdcfg[5], value);
1288 1289
		break;
	case QIXIS_ESDHC_ADAPTER_TYPE_SDMMC_LEGACY:
1290 1291 1292
		value = QIXIS_READ(pwr_ctl[1]);
		value |= QIXIS_EVDD_BY_SDHC_VS;
		QIXIS_WRITE(pwr_ctl[1], value);
1293 1294 1295 1296 1297 1298 1299 1300 1301 1302 1303 1304 1305 1306 1307 1308 1309 1310 1311 1312
		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

1313
#ifdef CONFIG_OF_LIBFDT
1314
__weak int esdhc_status_fixup(void *blob, const char *compat)
1315
{
1316
#ifdef CONFIG_FSL_ESDHC_PIN_MUX
1317
	if (!hwconfig("esdhc")) {
1318
		do_fixup_by_compat(blob, compat, "status", "disabled",
1319 1320
				sizeof("disabled"), 1);
		return 1;
1321
	}
1322
#endif
1323 1324 1325 1326 1327 1328 1329 1330 1331
	return 0;
}

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

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

1333 1334 1335 1336
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
	do_fixup_by_compat_u32(blob, compat, "peripheral-frequency",
			       gd->arch.sdhc_clk, 1);
#else
1337
	do_fixup_by_compat_u32(blob, compat, "clock-frequency",
1338
			       gd->arch.sdhc_clk, 1);
1339
#endif
1340 1341 1342 1343
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
	do_fixup_by_compat_u32(blob, compat, "adapter-type",
			       (u32)(gd->arch.sdhc_adapter), 1);
#endif
1344
}
1345
#endif
P
Peng Fan 已提交
1346

1347
#if CONFIG_IS_ENABLED(DM_MMC)
P
Peng Fan 已提交
1348
#include <asm/arch/clock.h>
P
Peng Fan 已提交
1349 1350 1351 1352
__weak void init_clk_usdhc(u32 index)
{
}

P
Peng Fan 已提交
1353 1354 1355
static int fsl_esdhc_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
1356
	struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
P
Peng Fan 已提交
1357
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
1358 1359 1360 1361
	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);
1362
#ifdef CONFIG_DM_REGULATOR
1363
	struct udevice *vqmmc_dev;
1364
#endif
P
Peng Fan 已提交
1365 1366
	fdt_addr_t addr;
	unsigned int val;
1367
	struct mmc *mmc;
P
Peng Fan 已提交
1368 1369
	int ret;

1370
	addr = dev_read_addr(dev);
P
Peng Fan 已提交
1371 1372 1373 1374 1375
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;

	priv->esdhc_regs = (struct fsl_esdhc *)addr;
	priv->dev = dev;
1376 1377 1378 1379 1380
	priv->mode = -1;
	if (data) {
		priv->flags = data->flags;
		priv->caps = data->caps;
	}
P
Peng Fan 已提交
1381

1382
	val = dev_read_u32_default(dev, "bus-width", -1);
P
Peng Fan 已提交
1383 1384 1385 1386 1387 1388 1389
	if (val == 8)
		priv->bus_width = 8;
	else if (val == 4)
		priv->bus_width = 4;
	else
		priv->bus_width = 1;

1390 1391 1392 1393 1394 1395 1396 1397 1398
	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;

1399
	if (dev_read_bool(dev, "non-removable")) {
P
Peng Fan 已提交
1400 1401 1402
		priv->non_removable = 1;
	 } else {
		priv->non_removable = 0;
1403
#ifdef CONFIG_DM_GPIO
1404 1405
		gpio_request_by_name(dev, "cd-gpios", 0, &priv->cd_gpio,
				     GPIOD_IS_IN);
1406
#endif
P
Peng Fan 已提交
1407 1408
	}

P
Peng Fan 已提交
1409 1410
	priv->wp_enable = 1;

1411
#ifdef CONFIG_DM_GPIO
1412 1413
	ret = gpio_request_by_name(dev, "wp-gpios", 0, &priv->wp_gpio,
				   GPIOD_IS_IN);
P
Peng Fan 已提交
1414 1415
	if (ret)
		priv->wp_enable = 0;
1416
#endif
1417 1418 1419 1420 1421 1422 1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434 1435 1436 1437 1438 1439

	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

1440 1441 1442
	if (fdt_get_property(fdt, node, "no-1-8-v", NULL))
		priv->caps &= ~(UHS_CAPS | MMC_MODE_HS200);

P
Peng Fan 已提交
1443 1444 1445 1446 1447 1448 1449 1450 1451 1452 1453 1454 1455 1456 1457 1458 1459 1460 1461
	/*
	 * 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 已提交
1462 1463 1464

	init_clk_usdhc(dev->seq);

P
Peng Fan 已提交
1465 1466 1467 1468 1469 1470
	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;
	}

1471
	ret = fsl_esdhc_init(priv, plat);
P
Peng Fan 已提交
1472 1473 1474 1475 1476
	if (ret) {
		dev_err(dev, "fsl_esdhc_init failure\n");
		return ret;
	}

1477 1478 1479 1480
	mmc = &plat->mmc;
	mmc->cfg = &plat->cfg;
	mmc->dev = dev;
	upriv->mmc = mmc;
P
Peng Fan 已提交
1481

1482
	return esdhc_init_common(priv, mmc);
P
Peng Fan 已提交
1483 1484
}

S
Simon Glass 已提交
1485
#if CONFIG_IS_ENABLED(DM_MMC)
1486 1487 1488 1489 1490 1491 1492 1493 1494 1495 1496 1497 1498 1499 1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513 1514
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,
1515 1516 1517
#ifdef MMC_SUPPORTS_TUNING
	.execute_tuning	= fsl_esdhc_execute_tuning,
#endif
1518 1519 1520
};
#endif

1521 1522 1523 1524 1525 1526 1527 1528
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 已提交
1529 1530 1531 1532 1533
static const struct udevice_id fsl_esdhc_ids[] = {
	{ .compatible = "fsl,imx6ul-usdhc", },
	{ .compatible = "fsl,imx6sx-usdhc", },
	{ .compatible = "fsl,imx6sl-usdhc", },
	{ .compatible = "fsl,imx6q-usdhc", },
1534
	{ .compatible = "fsl,imx7d-usdhc", .data = (ulong)&usdhc_imx7d_data,},
P
Peng Fan 已提交
1535
	{ .compatible = "fsl,imx7ulp-usdhc", },
1536
	{ .compatible = "fsl,esdhc", },
P
Peng Fan 已提交
1537 1538 1539
	{ /* sentinel */ }
};

1540 1541 1542 1543 1544 1545 1546 1547 1548
#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 已提交
1549 1550 1551 1552
U_BOOT_DRIVER(fsl_esdhc) = {
	.name	= "fsl-esdhc-mmc",
	.id	= UCLASS_MMC,
	.of_match = fsl_esdhc_ids,
1553 1554 1555 1556
	.ops	= &fsl_esdhc_ops,
#if CONFIG_IS_ENABLED(BLK)
	.bind	= fsl_esdhc_bind,
#endif
P
Peng Fan 已提交
1557
	.probe	= fsl_esdhc_probe,
1558
	.platdata_auto_alloc_size = sizeof(struct fsl_esdhc_plat),
P
Peng Fan 已提交
1559 1560 1561
	.priv_auto_alloc_size = sizeof(struct fsl_esdhc_priv),
};
#endif