fsl_esdhc.c 23.9 KB
Newer Older
1
// SPDX-License-Identifier: GPL-2.0+
2
/*
3
 * Copyright 2007, 2010-2011 Freescale Semiconductor, Inc
4
 * Copyright 2019 NXP Semiconductors
5 6 7 8 9 10 11 12 13 14
 * 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>
P
Peng Fan 已提交
15
#include <clk.h>
16
#include <errno.h>
17
#include <hwconfig.h>
18 19 20 21
#include <mmc.h>
#include <part.h>
#include <malloc.h>
#include <fsl_esdhc.h>
22
#include <fdt_support.h>
23
#include <asm/io.h>
P
Peng Fan 已提交
24
#include <dm.h>
25 26 27 28

DECLARE_GLOBAL_DATA_PTR;

struct fsl_esdhc {
29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46
	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 */
Y
Yangbo Lu 已提交
47
	char    reserved1[8];	/* reserved */
48 49 50
	uint    fevt;		/* Force event register */
	uint    admaes;		/* ADMA error status register */
	uint    adsaddr;	/* ADMA system address register */
Y
Yangbo Lu 已提交
51
	char    reserved2[160];
52
	uint    hostver;	/* Host controller version register */
Y
Yangbo Lu 已提交
53
	char    reserved3[4];	/* reserved */
54
	uint    dmaerraddr;	/* DMA error address register */
Y
Yangbo Lu 已提交
55
	char    reserved4[4];	/* reserved */
56
	uint    dmaerrattr;	/* DMA error attribute register */
Y
Yangbo Lu 已提交
57
	char    reserved5[4];	/* reserved */
58
	uint    hostcapblt2;	/* Host controller capabilities register 2 */
Y
Yangbo Lu 已提交
59 60
	char    reserved6[756];	/* reserved */
	uint    esdhcctl;	/* eSDHC control register */
61 62
};

63 64 65 66 67
struct fsl_esdhc_plat {
	struct mmc_config cfg;
	struct mmc mmc;
};

P
Peng Fan 已提交
68 69 70 71 72 73 74 75 76 77 78
/**
 * 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 已提交
79
 * @wp_enable: 1: enable checking wp; 0: no check
P
Peng Fan 已提交
80
 * @cd_gpio: gpio for card detection
P
Peng Fan 已提交
81
 * @wp_gpio: gpio for write protection
P
Peng Fan 已提交
82 83 84 85
 */
struct fsl_esdhc_priv {
	struct fsl_esdhc *esdhc_regs;
	unsigned int sdhc_clk;
P
Peng Fan 已提交
86
	struct clk per_clk;
87
	unsigned int clock;
88
#if !CONFIG_IS_ENABLED(DM_MMC)
P
Peng Fan 已提交
89
	struct mmc *mmc;
90
#endif
P
Peng Fan 已提交
91 92
	struct udevice *dev;
	int non_removable;
P
Peng Fan 已提交
93
	int wp_enable;
P
Peng Fan 已提交
94 95
};

96
/* Return the XFERTYP flags for a given command and data packet */
97
static uint esdhc_xfertyp(struct mmc_cmd *cmd, struct mmc_data *data)
98 99 100 101
{
	uint xfertyp = 0;

	if (data) {
102 103 104 105
		xfertyp |= XFERTYP_DPSEL;
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
		xfertyp |= XFERTYP_DMAEN;
#endif
106 107 108
		if (data->blocks > 1) {
			xfertyp |= XFERTYP_MSBSEL;
			xfertyp |= XFERTYP_BCEN;
109 110 111
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
			xfertyp |= XFERTYP_AC12EN;
#endif
112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
		}

		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;

129 130
	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
		xfertyp |= XFERTYP_CMDTYP_ABORT;
131

132 133 134
	return XFERTYP_CMD(cmd->cmdidx) | xfertyp;
}

135 136 137 138
#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
/*
 * PIO Read/Write Mode reduce the performace as DMA is not used in this mode.
 */
139 140
static void esdhc_pio_read_write(struct fsl_esdhc_priv *priv,
				 struct mmc_data *data)
141
{
P
Peng Fan 已提交
142
	struct fsl_esdhc *regs = priv->esdhc_regs;
143 144 145 146 147
	uint blocks;
	char *buffer;
	uint databuf;
	uint size;
	uint irqstat;
148
	ulong start;
149 150 151 152 153

	if (data->flags & MMC_DATA_READ) {
		blocks = data->blocks;
		buffer = data->dest;
		while (blocks) {
154
			start = get_timer(0);
155 156
			size = data->blocksize;
			irqstat = esdhc_read32(&regs->irqstat);
157 158 159 160 161
			while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BREN)) {
				if (get_timer(start) > PIO_TIMEOUT) {
					printf("\nData Read Failed in PIO Mode.");
					return;
				}
162 163 164 165 166 167 168 169 170 171 172 173 174
			}
			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;
175
		buffer = (char *)data->src;
176
		while (blocks) {
177
			start = get_timer(0);
178 179
			size = data->blocksize;
			irqstat = esdhc_read32(&regs->irqstat);
180 181 182 183 184
			while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_BWEN)) {
				if (get_timer(start) > PIO_TIMEOUT) {
					printf("\nData Write Failed in PIO Mode.");
					return;
				}
185 186 187 188 189 190 191 192 193 194 195 196 197 198 199
			}
			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

200 201
static int esdhc_setup_data(struct fsl_esdhc_priv *priv, struct mmc *mmc,
			    struct mmc_data *data)
202 203
{
	int timeout;
P
Peng Fan 已提交
204
	struct fsl_esdhc *regs = priv->esdhc_regs;
Y
Yangbo Lu 已提交
205
#if defined(CONFIG_FSL_LAYERSCAPE)
206 207
	dma_addr_t addr;
#endif
208
	uint wml_value;
209 210 211 212

	wml_value = data->blocksize/4;

	if (data->flags & MMC_DATA_READ) {
213 214
		if (wml_value > WML_RD_WML_MAX)
			wml_value = WML_RD_WML_MAX_VAL;
215

216
		esdhc_clrsetbits32(&regs->wml, WML_RD_WML_MASK, wml_value);
217
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
Y
Yangbo Lu 已提交
218
#if defined(CONFIG_FSL_LAYERSCAPE)
219 220 221 222 223 224
		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
225
		esdhc_write32(&regs->dsaddr, (u32)data->dest);
226
#endif
227
#endif
228
	} else {
229
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
230 231 232
		flush_dcache_range((ulong)data->src,
				   (ulong)data->src+data->blocks
					 *data->blocksize);
233
#endif
234 235
		if (wml_value > WML_WR_WML_MAX)
			wml_value = WML_WR_WML_MAX_VAL;
P
Peng Fan 已提交
236 237 238 239
		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");
240
				return -ETIMEDOUT;
P
Peng Fan 已提交
241
			}
242
		}
243 244 245

		esdhc_clrsetbits32(&regs->wml, WML_WR_WML_MASK,
					wml_value << 16);
246
#ifndef CONFIG_SYS_FSL_ESDHC_USE_PIO
Y
Yangbo Lu 已提交
247
#if defined(CONFIG_FSL_LAYERSCAPE)
248 249 250 251 252 253
		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
254
		esdhc_write32(&regs->dsaddr, (u32)data->src);
255
#endif
256
#endif
257 258
	}

259
	esdhc_write32(&regs->blkattr, data->blocks << 16 | data->blocksize);
260 261

	/* Calculate the timeout period for data transactions */
262 263 264 265 266
	/*
	 * 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
267
	 *		= (mmc->clock * 1/4) SD Clock cycles
268
	 * As 1) >=  2)
269
	 * => (2^(timeout+13)) >= mmc->clock * 1/4
270
	 * Taking log2 both the sides
271
	 * => timeout + 13 >= log2(mmc->clock/4)
272
	 * Rounding up to next power of 2
273 274
	 * => timeout + 13 = log2(mmc->clock/4) + 1
	 * => timeout + 13 = fls(mmc->clock/4)
275 276 277 278 279 280 281
	 *
	 * 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)
282
	 */
283
	timeout = fls(mmc->clock/2);
284 285 286 287 288 289 290 291
	timeout -= 13;

	if (timeout > 14)
		timeout = 14;

	if (timeout < 0)
		timeout = 0;

292 293 294 295 296
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC_A001
	if ((timeout == 4) || (timeout == 8) || (timeout == 12))
		timeout++;
#endif

297 298 299
#ifdef ESDHCI_QUIRK_BROKEN_TIMEOUT_VALUE
	timeout = 0xE;
#endif
300
	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, timeout << 16);
301 302 303 304

	return 0;
}

305 306 307
static void check_and_invalidate_dcache_range
	(struct mmc_cmd *cmd,
	 struct mmc_data *data) {
308
	unsigned start = 0;
309
	unsigned end = 0;
310 311
	unsigned size = roundup(ARCH_DMA_MINALIGN,
				data->blocks*data->blocksize);
Y
Yangbo Lu 已提交
312
#if defined(CONFIG_FSL_LAYERSCAPE)
313 314 315 316 317 318 319
	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);
320 321
#else
	start = (unsigned)data->dest;
322
#endif
323
	end = start + size;
324 325
	invalidate_dcache_range(start, end);
}
326

327 328 329 330
/*
 * Sends a command out on the bus.  Takes the mmc pointer,
 * a command pointer, and an optional data pointer.
 */
331 332
static int esdhc_send_cmd_common(struct fsl_esdhc_priv *priv, struct mmc *mmc,
				 struct mmc_cmd *cmd, struct mmc_data *data)
333
{
334
	int	err = 0;
335 336
	uint	xfertyp;
	uint	irqstat;
337
	u32	flags = IRQSTAT_CC | IRQSTAT_CTOE;
P
Peng Fan 已提交
338
	struct fsl_esdhc *regs = priv->esdhc_regs;
339
	unsigned long start;
340

341 342 343 344 345
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC111
	if (cmd->cmdidx == MMC_CMD_STOP_TRANSMISSION)
		return 0;
#endif

346
	esdhc_write32(&regs->irqstat, -1);
347 348 349 350

	sync();

	/* Wait for the bus to be idle */
351 352 353
	while ((esdhc_read32(&regs->prsstat) & PRSSTAT_CICHB) ||
			(esdhc_read32(&regs->prsstat) & PRSSTAT_CIDHB))
		;
354

355 356
	while (esdhc_read32(&regs->prsstat) & PRSSTAT_DLA)
		;
357 358 359 360 361 362 363 364 365 366

	/* 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) {
367
		err = esdhc_setup_data(priv, mmc, data);
368 369
		if(err)
			return err;
370 371 372

		if (data->flags & MMC_DATA_READ)
			check_and_invalidate_dcache_range(cmd, data);
373 374 375 376 377
	}

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

378 379 380
	/* Mask all irqs */
	esdhc_write32(&regs->irqsigen, 0);

381
	/* Send the command */
382 383
	esdhc_write32(&regs->cmdarg, cmd->cmdarg);
	esdhc_write32(&regs->xfertyp, xfertyp);
384

385
	/* Wait for the command to complete */
386 387 388 389 390 391 392
	start = get_timer(0);
	while (!(esdhc_read32(&regs->irqstat) & flags)) {
		if (get_timer(start) > 1000) {
			err = -ETIMEDOUT;
			goto out;
		}
	}
393

394
	irqstat = esdhc_read32(&regs->irqstat);
395

396
	if (irqstat & CMD_ERR) {
397
		err = -ECOMM;
398
		goto out;
399 400
	}

401
	if (irqstat & IRQSTAT_CTOE) {
402
		err = -ETIMEDOUT;
403 404
		goto out;
	}
405

406 407
	/* Workaround for ESDHC errata ENGcm03648 */
	if (!data && (cmd->resp_type & MMC_RSP_BUSY)) {
408
		int timeout = 6000;
409

410
		/* Poll on DATA0 line for cmd with busy signal for 600 ms */
411 412 413 414 415 416 417 418
		while (timeout > 0 && !(esdhc_read32(&regs->prsstat) &
					PRSSTAT_DAT0)) {
			udelay(100);
			timeout--;
		}

		if (timeout <= 0) {
			printf("Timeout waiting for DAT0 to go high!\n");
419
			err = -ETIMEDOUT;
420
			goto out;
421 422 423
		}
	}

424 425 426 427
	/* Copy the response to the response buffer */
	if (cmd->resp_type & MMC_RSP_136) {
		u32 cmdrsp3, cmdrsp2, cmdrsp1, cmdrsp0;

428 429 430 431
		cmdrsp3 = esdhc_read32(&regs->cmdrsp3);
		cmdrsp2 = esdhc_read32(&regs->cmdrsp2);
		cmdrsp1 = esdhc_read32(&regs->cmdrsp1);
		cmdrsp0 = esdhc_read32(&regs->cmdrsp0);
R
Rabin Vincent 已提交
432 433 434 435
		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);
436
	} else
437
		cmd->response[0] = esdhc_read32(&regs->cmdrsp0);
438 439 440

	/* Wait until all of the blocks are transferred */
	if (data) {
441
#ifdef CONFIG_SYS_FSL_ESDHC_USE_PIO
442
		esdhc_pio_read_write(priv, data);
443
#else
444
		do {
445
			irqstat = esdhc_read32(&regs->irqstat);
446

447
			if (irqstat & IRQSTAT_DTOE) {
448
				err = -ETIMEDOUT;
449 450
				goto out;
			}
451

452
			if (irqstat & DATA_ERR) {
453
				err = -ECOMM;
454 455
				goto out;
			}
456
		} while ((irqstat & DATA_COMPLETE) != DATA_COMPLETE);
457

458 459 460 461 462
		/*
		 * Need invalidate the dcache here again to avoid any
		 * cache-fill during the DMA operations such as the
		 * speculative pre-fetching etc.
		 */
463
		if (data->flags & MMC_DATA_READ) {
464
			check_and_invalidate_dcache_range(cmd, data);
465
		}
466
#endif
467 468
	}

469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485
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))
				;
		}
	}

486
	esdhc_write32(&regs->irqstat, -1);
487

488
	return err;
489 490
}

491
static void set_sysctl(struct fsl_esdhc_priv *priv, struct mmc *mmc, uint clock)
492
{
493
	struct fsl_esdhc *regs = priv->esdhc_regs;
494 495
	int div = 1;
	int pre_div = 2;
496 497 498
	unsigned int sdhc_clk = priv->sdhc_clk;
	u32 time_out;
	u32 value;
499 500
	uint clk;

501 502
	if (clock < mmc->cfg->f_min)
		clock = mmc->cfg->f_min;
503

504
	while (sdhc_clk / (16 * pre_div) > clock && pre_div < 256)
505
		pre_div *= 2;
506

507
	while (sdhc_clk / (div * pre_div) > clock && div < 16)
508
		div++;
509

510
	pre_div >>= 1;
511 512 513 514
	div -= 1;

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

515
	esdhc_clrbits32(&regs->sysctl, SYSCTL_CKEN);
516 517

	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_CLOCK_MASK, clk);
518

519 520 521 522 523 524 525 526 527 528
	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);
	}
529

530
	esdhc_setbits32(&regs->sysctl, SYSCTL_PEREN | SYSCTL_CKEN);
531 532
}

533
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
534
static void esdhc_clock_control(struct fsl_esdhc_priv *priv, bool enable)
535
{
P
Peng Fan 已提交
536
	struct fsl_esdhc *regs = priv->esdhc_regs;
537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557 558 559 560 561
	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

562
static int esdhc_set_ios_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
563
{
P
Peng Fan 已提交
564
	struct fsl_esdhc *regs = priv->esdhc_regs;
565

566 567
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
	/* Select to use peripheral clock */
568
	esdhc_clock_control(priv, false);
Y
Yangbo Lu 已提交
569
	esdhc_setbits32(&regs->esdhcctl, ESDHCCTL_PCS);
570
	esdhc_clock_control(priv, true);
571
#endif
572
	/* Set the clock speed */
573 574 575
	if (priv->clock != mmc->clock)
		set_sysctl(priv, mmc, mmc->clock);

576
	/* Set the bus width */
577
	esdhc_clrbits32(&regs->proctl, PROCTL_DTW_4 | PROCTL_DTW_8);
578 579

	if (mmc->bus_width == 4)
580
		esdhc_setbits32(&regs->proctl, PROCTL_DTW_4);
581
	else if (mmc->bus_width == 8)
582 583
		esdhc_setbits32(&regs->proctl, PROCTL_DTW_8);

584
	return 0;
585 586
}

587
static int esdhc_init_common(struct fsl_esdhc_priv *priv, struct mmc *mmc)
588
{
P
Peng Fan 已提交
589
	struct fsl_esdhc *regs = priv->esdhc_regs;
590
	ulong start;
591

592
	/* Reset the entire host controller */
593
	esdhc_setbits32(&regs->sysctl, SYSCTL_RSTA);
594 595

	/* Wait until the controller is available */
596 597 598 599 600
	start = get_timer(0);
	while ((esdhc_read32(&regs->sysctl) & SYSCTL_RSTA)) {
		if (get_timer(start) > 1000)
			return -ETIMEDOUT;
	}
601

602
	/* Enable cache snooping */
Y
Yangbo Lu 已提交
603
	esdhc_write32(&regs->esdhcctl, 0x00000040);
604

605
	esdhc_setbits32(&regs->sysctl, SYSCTL_HCKEN | SYSCTL_IPGEN);
606 607

	/* Set the initial clock speed */
608
	mmc_set_clock(mmc, 400000, MMC_CLK_ENABLE);
609 610

	/* Disable the BRR and BWR bits in IRQSTAT */
611
	esdhc_clrbits32(&regs->irqstaten, IRQSTATEN_BRR | IRQSTATEN_BWR);
612 613

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

616 617
	/* Set timout to the maximum value */
	esdhc_clrsetbits32(&regs->sysctl, SYSCTL_TIMEOUT_MASK, 14 << 16);
618

619 620
	return 0;
}
621

622
static int esdhc_getcd_common(struct fsl_esdhc_priv *priv)
623
{
P
Peng Fan 已提交
624
	struct fsl_esdhc *regs = priv->esdhc_regs;
625 626
	int timeout = 1000;

627 628 629 630
#ifdef CONFIG_ESDHC_DETECT_QUIRK
	if (CONFIG_ESDHC_DETECT_QUIRK)
		return 1;
#endif
P
Peng Fan 已提交
631

632
#if CONFIG_IS_ENABLED(DM_MMC)
P
Peng Fan 已提交
633 634 635 636
	if (priv->non_removable)
		return 1;
#endif

637 638
	while (!(esdhc_read32(&regs->prsstat) & PRSSTAT_CINS) && --timeout)
		udelay(1000);
639

640
	return timeout > 0;
641 642
}

S
Simon Glass 已提交
643
#if !CONFIG_IS_ENABLED(DM_MMC)
644 645 646 647 648 649 650 651 652 653 654 655 656 657 658 659 660 661 662 663 664 665 666 667 668 669 670 671 672
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);
}

673
static const struct mmc_ops esdhc_ops = {
674 675
	.getcd		= esdhc_getcd,
	.init		= esdhc_init,
676 677 678
	.send_cmd	= esdhc_send_cmd,
	.set_ios	= esdhc_set_ios,
};
679
#endif
680

681 682
static int fsl_esdhc_init(struct fsl_esdhc_priv *priv,
			  struct fsl_esdhc_plat *plat)
683
{
684
	struct mmc_config *cfg;
685
	struct fsl_esdhc *regs;
Y
Yangbo Lu 已提交
686
	u32 caps;
687

P
Peng Fan 已提交
688 689
	if (!priv)
		return -EINVAL;
690

P
Peng Fan 已提交
691
	regs = priv->esdhc_regs;
692

693
	cfg = &plat->cfg;
694
#ifndef CONFIG_DM_MMC
695
	memset(cfg, '\0', sizeof(*cfg));
696
#endif
697

698
	caps = esdhc_read32(&regs->hostcapblt);
699
#ifdef CONFIG_SYS_FSL_ERRATUM_ESDHC135
Y
Yangbo Lu 已提交
700
	caps &= ~(HOSTCAPBLT_SRS | HOSTCAPBLT_VS18 | HOSTCAPBLT_VS30);
701
#endif
702
#ifdef CONFIG_SYS_FSL_MMC_HAS_CAPBLT_VS33
Y
Yangbo Lu 已提交
703
	caps |= HOSTCAPBLT_VS33;
704
#endif
Y
Yangbo Lu 已提交
705 706 707 708 709 710
	if (caps & HOSTCAPBLT_VS18)
		cfg->voltages |= MMC_VDD_165_195;
	if (caps & HOSTCAPBLT_VS30)
		cfg->voltages |= MMC_VDD_29_30 | MMC_VDD_30_31;
	if (caps & HOSTCAPBLT_VS33)
		cfg->voltages |= MMC_VDD_32_33 | MMC_VDD_33_34;
711

712
	cfg->name = "FSL_SDHC";
S
Simon Glass 已提交
713
#if !CONFIG_IS_ENABLED(DM_MMC)
714
	cfg->ops = &esdhc_ops;
715
#endif
716

Y
Yangbo Lu 已提交
717
	if (caps & HOSTCAPBLT_HSS)
718
		cfg->host_caps |= MMC_MODE_HS_52MHz | MMC_MODE_HS;
719

720
	cfg->f_min = 400000;
721
	cfg->f_max = min(priv->sdhc_clk, (u32)200000000);
722

723
	cfg->b_max = CONFIG_SYS_MMC_MAX_BLK_COUNT;
724

P
Peng Fan 已提交
725 726 727
	return 0;
}

728
#if !CONFIG_IS_ENABLED(DM_MMC)
P
Peng Fan 已提交
729 730
int fsl_esdhc_initialize(bd_t *bis, struct fsl_esdhc_cfg *cfg)
{
731
	struct fsl_esdhc_plat *plat;
P
Peng Fan 已提交
732
	struct fsl_esdhc_priv *priv;
733
	struct mmc_config *mmc_cfg;
734
	struct mmc *mmc;
P
Peng Fan 已提交
735 736 737 738 739 740 741 742
	int ret;

	if (!cfg)
		return -EINVAL;

	priv = calloc(sizeof(struct fsl_esdhc_priv), 1);
	if (!priv)
		return -ENOMEM;
743 744 745 746 747
	plat = calloc(sizeof(struct fsl_esdhc_plat), 1);
	if (!plat) {
		free(priv);
		return -ENOMEM;
	}
P
Peng Fan 已提交
748

749 750 751 752 753 754 755 756 757 758 759 760 761 762 763 764 765
	priv->esdhc_regs = (struct fsl_esdhc *)(unsigned long)(cfg->esdhc_base);
	priv->sdhc_clk = cfg->sdhc_clk;
	priv->wp_enable  = cfg->wp_enable;

	mmc_cfg = &plat->cfg;

	if (cfg->max_bus_width == 8) {
		mmc_cfg->host_caps |= MMC_MODE_1BIT | MMC_MODE_4BIT |
				      MMC_MODE_8BIT;
	} else if (cfg->max_bus_width == 4) {
		mmc_cfg->host_caps |= MMC_MODE_1BIT | MMC_MODE_4BIT;
	} else if (cfg->max_bus_width == 1) {
		mmc_cfg->host_caps |= MMC_MODE_1BIT;
	} else {
		mmc_cfg->host_caps |= MMC_MODE_1BIT | MMC_MODE_4BIT |
				      MMC_MODE_8BIT;
		printf("No max bus width provided. Assume 8-bit supported.\n");
P
Peng Fan 已提交
766 767
	}

768 769 770 771
#ifdef CONFIG_ESDHC_DETECT_8_BIT_QUIRK
	if (CONFIG_ESDHC_DETECT_8_BIT_QUIRK)
		mmc_cfg->host_caps &= ~MMC_MODE_8BIT;
#endif
772
	ret = fsl_esdhc_init(priv, plat);
P
Peng Fan 已提交
773 774
	if (ret) {
		debug("%s init failure\n", __func__);
775
		free(plat);
P
Peng Fan 已提交
776 777 778 779
		free(priv);
		return ret;
	}

780 781 782 783 784 785
	mmc = mmc_create(&plat->cfg, priv);
	if (!mmc)
		return -EIO;

	priv->mmc = mmc;

786 787 788 789 790
	return 0;
}

int fsl_esdhc_mmc_init(bd_t *bis)
{
791 792
	struct fsl_esdhc_cfg *cfg;

F
Fabio Estevam 已提交
793
	cfg = calloc(sizeof(struct fsl_esdhc_cfg), 1);
794
	cfg->esdhc_base = CONFIG_SYS_FSL_ESDHC_ADDR;
795
	cfg->sdhc_clk = gd->arch.sdhc_clk;
796
	return fsl_esdhc_initialize(bis, cfg);
797
}
798
#endif
799

800 801 802 803 804 805 806 807 808 809 810
#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:
811 812 813
		value = QIXIS_READ(brdcfg[5]);
		value |= (QIXIS_DAT4 | QIXIS_DAT5_6_7);
		QIXIS_WRITE(brdcfg[5], value);
814 815
		break;
	case QIXIS_ESDHC_ADAPTER_TYPE_SDMMC_LEGACY:
816 817 818
		value = QIXIS_READ(pwr_ctl[1]);
		value |= QIXIS_EVDD_BY_SDHC_VS;
		QIXIS_WRITE(pwr_ctl[1], value);
819 820 821 822 823 824 825 826 827 828 829 830 831 832 833 834 835 836 837 838
		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

839
#ifdef CONFIG_OF_LIBFDT
840
__weak int esdhc_status_fixup(void *blob, const char *compat)
841
{
842
#ifdef CONFIG_FSL_ESDHC_PIN_MUX
843
	if (!hwconfig("esdhc")) {
844
		do_fixup_by_compat(blob, compat, "status", "disabled",
845 846
				sizeof("disabled"), 1);
		return 1;
847
	}
848
#endif
849 850 851 852 853 854 855 856 857
	return 0;
}

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

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

859 860 861 862
#ifdef CONFIG_FSL_ESDHC_USE_PERIPHERAL_CLK
	do_fixup_by_compat_u32(blob, compat, "peripheral-frequency",
			       gd->arch.sdhc_clk, 1);
#else
863
	do_fixup_by_compat_u32(blob, compat, "clock-frequency",
864
			       gd->arch.sdhc_clk, 1);
865
#endif
866 867 868 869
#ifdef CONFIG_FSL_ESDHC_ADAPTER_IDENT
	do_fixup_by_compat_u32(blob, compat, "adapter-type",
			       (u32)(gd->arch.sdhc_adapter), 1);
#endif
870
}
871
#endif
P
Peng Fan 已提交
872

873
#if CONFIG_IS_ENABLED(DM_MMC)
874
#ifndef CONFIG_PPC
P
Peng Fan 已提交
875
#include <asm/arch/clock.h>
876
#endif
P
Peng Fan 已提交
877 878 879
static int fsl_esdhc_probe(struct udevice *dev)
{
	struct mmc_uclass_priv *upriv = dev_get_uclass_priv(dev);
880
	struct fsl_esdhc_plat *plat = dev_get_platdata(dev);
P
Peng Fan 已提交
881 882
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);
	fdt_addr_t addr;
883
	struct mmc *mmc;
P
Peng Fan 已提交
884 885
	int ret;

886
	addr = dev_read_addr(dev);
P
Peng Fan 已提交
887 888
	if (addr == FDT_ADDR_T_NONE)
		return -EINVAL;
889 890 891
#ifdef CONFIG_PPC
	priv->esdhc_regs = (struct fsl_esdhc *)lower_32_bits(addr);
#else
P
Peng Fan 已提交
892
	priv->esdhc_regs = (struct fsl_esdhc *)addr;
893
#endif
P
Peng Fan 已提交
894 895
	priv->dev = dev;

896
	if (dev_read_bool(dev, "non-removable")) {
P
Peng Fan 已提交
897 898 899 900 901
		priv->non_removable = 1;
	 } else {
		priv->non_removable = 0;
	}

Y
Yangbo Lu 已提交
902
	priv->wp_enable = 1;
P
Peng Fan 已提交
903

P
Peng Fan 已提交
904 905 906 907 908 909 910 911 912 913 914 915 916 917 918
	if (IS_ENABLED(CONFIG_CLK)) {
		/* Assigned clock already set clock */
		ret = clk_get_by_name(dev, "per", &priv->per_clk);
		if (ret) {
			printf("Failed to get per_clk\n");
			return ret;
		}
		ret = clk_enable(&priv->per_clk);
		if (ret) {
			printf("Failed to enable per_clk\n");
			return ret;
		}

		priv->sdhc_clk = clk_get_rate(&priv->per_clk);
	} else {
919
#ifndef CONFIG_PPC
P
Peng Fan 已提交
920
		priv->sdhc_clk = mxc_get_clock(MXC_ESDHC_CLK + dev->seq);
921 922 923
#else
		priv->sdhc_clk = gd->arch.sdhc_clk;
#endif
P
Peng Fan 已提交
924 925 926 927
		if (priv->sdhc_clk <= 0) {
			dev_err(dev, "Unable to get clk for %s\n", dev->name);
			return -EINVAL;
		}
P
Peng Fan 已提交
928 929
	}

930
	ret = fsl_esdhc_init(priv, plat);
P
Peng Fan 已提交
931 932 933 934 935
	if (ret) {
		dev_err(dev, "fsl_esdhc_init failure\n");
		return ret;
	}

936 937
	mmc_of_parse(dev, &plat->cfg);

938 939 940
	mmc = &plat->mmc;
	mmc->cfg = &plat->cfg;
	mmc->dev = dev;
941

942
	upriv->mmc = mmc;
P
Peng Fan 已提交
943

944
	return esdhc_init_common(priv, mmc);
P
Peng Fan 已提交
945 946
}

947 948 949 950 951 952 953 954 955 956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974
static int fsl_esdhc_get_cd(struct udevice *dev)
{
	struct fsl_esdhc_priv *priv = dev_get_priv(dev);

	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,
975 976 977
#ifdef MMC_SUPPORTS_TUNING
	.execute_tuning = fsl_esdhc_execute_tuning,
#endif
978 979
};

P
Peng Fan 已提交
980
static const struct udevice_id fsl_esdhc_ids[] = {
981
	{ .compatible = "fsl,esdhc", },
P
Peng Fan 已提交
982 983 984
	{ /* sentinel */ }
};

985 986 987 988 989 990 991
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);
}

P
Peng Fan 已提交
992 993 994 995
U_BOOT_DRIVER(fsl_esdhc) = {
	.name	= "fsl-esdhc-mmc",
	.id	= UCLASS_MMC,
	.of_match = fsl_esdhc_ids,
996 997
	.ops	= &fsl_esdhc_ops,
	.bind	= fsl_esdhc_bind,
P
Peng Fan 已提交
998
	.probe	= fsl_esdhc_probe,
999
	.platdata_auto_alloc_size = sizeof(struct fsl_esdhc_plat),
P
Peng Fan 已提交
1000 1001 1002
	.priv_auto_alloc_size = sizeof(struct fsl_esdhc_priv),
};
#endif