sdhci-esdhc-imx.c 19.6 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
/*
 * Freescale eSDHC i.MX controller driver for the platform bus.
 *
 * derived from the OF-version.
 *
 * Copyright (c) 2010 Pengutronix e.K.
 *   Author: Wolfram Sang <w.sang@pengutronix.de>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License.
 */

#include <linux/io.h>
#include <linux/delay.h>
#include <linux/err.h>
#include <linux/clk.h>
18
#include <linux/gpio.h>
19
#include <linux/module.h>
20
#include <linux/slab.h>
21
#include <linux/mmc/host.h>
22 23
#include <linux/mmc/mmc.h>
#include <linux/mmc/sdio.h>
24
#include <linux/mmc/slot-gpio.h>
25 26 27
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_gpio.h>
28
#include <linux/pinctrl/consumer.h>
29
#include <linux/platform_data/mmc-esdhc-imx.h>
30 31 32
#include "sdhci-pltfm.h"
#include "sdhci-esdhc.h"

33
#define	ESDHC_CTRL_D3CD			0x08
34
/* VENDOR SPEC register */
35 36 37 38
#define ESDHC_VENDOR_SPEC		0xc0
#define  ESDHC_VENDOR_SPEC_SDIO_QUIRK	(1 << 1)
#define ESDHC_WTMK_LVL			0x44
#define ESDHC_MIX_CTRL			0x48
39 40 41
#define  ESDHC_MIX_CTRL_AC23EN		(1 << 7)
/* Bits 3 and 6 are not SDHCI standard definitions */
#define  ESDHC_MIX_CTRL_SDHCI_MASK	0xb7
42

43 44 45 46 47 48 49
/*
 * Our interpretation of the SDHCI_HOST_CONTROL register
 */
#define ESDHC_CTRL_4BITBUS		(0x1 << 1)
#define ESDHC_CTRL_8BITBUS		(0x2 << 1)
#define ESDHC_CTRL_BUSWIDTH_MASK	(0x3 << 1)

R
Richard Zhu 已提交
50 51 52 53 54 55
/*
 * There is an INT DMA ERR mis-match between eSDHC and STD SDHC SPEC:
 * Bit25 is used in STD SPEC, and is reserved in fsl eSDHC design,
 * but bit28 is used as the INT DMA ERR in fsl eSDHC design.
 * Define this macro DMA error INT for fsl eSDHC
 */
56
#define ESDHC_INT_VENDOR_SPEC_DMA_ERR	(1 << 28)
R
Richard Zhu 已提交
57

58 59 60 61 62 63 64 65 66 67 68 69
/*
 * The CMDTYPE of the CMD register (offset 0xE) should be set to
 * "11" when the STOP CMD12 is issued on imx53 to abort one
 * open ended multi-blk IO. Otherwise the TC INT wouldn't
 * be generated.
 * In exact block transfer, the controller doesn't complete the
 * operations automatically as required at the end of the
 * transfer and remains on hold if the abort command is not sent.
 * As a result, the TC flag is not asserted and SW  received timeout
 * exeception. Bit1 of Vendor Spec registor is used to fix it.
 */
#define ESDHC_FLAG_MULTIBLK_NO_INT	(1 << 1)
70

71 72 73 74 75
enum imx_esdhc_type {
	IMX25_ESDHC,
	IMX35_ESDHC,
	IMX51_ESDHC,
	IMX53_ESDHC,
76
	IMX6Q_USDHC,
77 78
};

79 80 81
struct pltfm_imx_data {
	int flags;
	u32 scratchpad;
82
	enum imx_esdhc_type devtype;
83
	struct pinctrl *pinctrl;
84
	struct esdhc_platform_data boarddata;
85 86 87
	struct clk *clk_ipg;
	struct clk *clk_ahb;
	struct clk *clk_per;
88 89 90 91 92 93
	enum {
		NO_CMD_PENDING,      /* no multiblock command pending*/
		MULTIBLK_IN_PROCESS, /* exact multiblock cmd in process */
		WAIT_FOR_INT,        /* sent CMD12, waiting for response INT */
	} multiblock_status;

94 95
};

96 97 98 99 100 101 102 103 104 105 106 107 108
static struct platform_device_id imx_esdhc_devtype[] = {
	{
		.name = "sdhci-esdhc-imx25",
		.driver_data = IMX25_ESDHC,
	}, {
		.name = "sdhci-esdhc-imx35",
		.driver_data = IMX35_ESDHC,
	}, {
		.name = "sdhci-esdhc-imx51",
		.driver_data = IMX51_ESDHC,
	}, {
		.name = "sdhci-esdhc-imx53",
		.driver_data = IMX53_ESDHC,
109 110 111
	}, {
		.name = "sdhci-usdhc-imx6q",
		.driver_data = IMX6Q_USDHC,
112 113 114 115 116 117
	}, {
		/* sentinel */
	}
};
MODULE_DEVICE_TABLE(platform, imx_esdhc_devtype);

118 119 120 121 122
static const struct of_device_id imx_esdhc_dt_ids[] = {
	{ .compatible = "fsl,imx25-esdhc", .data = &imx_esdhc_devtype[IMX25_ESDHC], },
	{ .compatible = "fsl,imx35-esdhc", .data = &imx_esdhc_devtype[IMX35_ESDHC], },
	{ .compatible = "fsl,imx51-esdhc", .data = &imx_esdhc_devtype[IMX51_ESDHC], },
	{ .compatible = "fsl,imx53-esdhc", .data = &imx_esdhc_devtype[IMX53_ESDHC], },
123
	{ .compatible = "fsl,imx6q-usdhc", .data = &imx_esdhc_devtype[IMX6Q_USDHC], },
124 125 126 127
	{ /* sentinel */ }
};
MODULE_DEVICE_TABLE(of, imx_esdhc_dt_ids);

128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147
static inline int is_imx25_esdhc(struct pltfm_imx_data *data)
{
	return data->devtype == IMX25_ESDHC;
}

static inline int is_imx35_esdhc(struct pltfm_imx_data *data)
{
	return data->devtype == IMX35_ESDHC;
}

static inline int is_imx51_esdhc(struct pltfm_imx_data *data)
{
	return data->devtype == IMX51_ESDHC;
}

static inline int is_imx53_esdhc(struct pltfm_imx_data *data)
{
	return data->devtype == IMX53_ESDHC;
}

148 149 150 151 152
static inline int is_imx6q_usdhc(struct pltfm_imx_data *data)
{
	return data->devtype == IMX6Q_USDHC;
}

153 154 155 156 157 158 159 160
static inline void esdhc_clrset_le(struct sdhci_host *host, u32 mask, u32 val, int reg)
{
	void __iomem *base = host->ioaddr + (reg & ~0x3);
	u32 shift = (reg & 0x3) * 8;

	writel(((readl(base) & ~(mask << shift)) | (val << shift)), base);
}

161 162
static u32 esdhc_readl_le(struct sdhci_host *host, int reg)
{
163 164
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct pltfm_imx_data *imx_data = pltfm_host->priv;
165 166
	u32 val = readl(host->ioaddr + reg);

R
Richard Zhu 已提交
167 168 169 170 171 172 173 174 175 176 177 178 179 180 181
	if (unlikely(reg == SDHCI_CAPABILITIES)) {
		/* In FSL esdhc IC module, only bit20 is used to indicate the
		 * ADMA2 capability of esdhc, but this bit is messed up on
		 * some SOCs (e.g. on MX25, MX35 this bit is set, but they
		 * don't actually support ADMA2). So set the BROKEN_ADMA
		 * uirk on MX25/35 platforms.
		 */

		if (val & SDHCI_CAN_DO_ADMA1) {
			val &= ~SDHCI_CAN_DO_ADMA1;
			val |= SDHCI_CAN_DO_ADMA2;
		}
	}

	if (unlikely(reg == SDHCI_INT_STATUS)) {
182 183
		if (val & ESDHC_INT_VENDOR_SPEC_DMA_ERR) {
			val &= ~ESDHC_INT_VENDOR_SPEC_DMA_ERR;
R
Richard Zhu 已提交
184 185
			val |= SDHCI_INT_ADMA_ERROR;
		}
186 187 188 189 190 191 192 193 194 195 196 197

		/*
		 * mask off the interrupt we get in response to the manually
		 * sent CMD12
		 */
		if ((imx_data->multiblock_status == WAIT_FOR_INT) &&
		    ((val & SDHCI_INT_RESPONSE) == SDHCI_INT_RESPONSE)) {
			val &= ~SDHCI_INT_RESPONSE;
			writel(SDHCI_INT_RESPONSE, host->ioaddr +
						   SDHCI_INT_STATUS);
			imx_data->multiblock_status = NO_CMD_PENDING;
		}
R
Richard Zhu 已提交
198 199
	}

200 201 202 203 204
	return val;
}

static void esdhc_writel_le(struct sdhci_host *host, u32 val, int reg)
{
205 206
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct pltfm_imx_data *imx_data = pltfm_host->priv;
207 208 209 210 211 212 213 214 215 216 217 218 219
	u32 data;

	if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
		if (val & SDHCI_INT_CARD_INT) {
			/*
			 * Clear and then set D3CD bit to avoid missing the
			 * card interrupt.  This is a eSDHC controller problem
			 * so we need to apply the following workaround: clear
			 * and set D3CD bit will make eSDHC re-sample the card
			 * interrupt. In case a card interrupt was lost,
			 * re-sample it by the following steps.
			 */
			data = readl(host->ioaddr + SDHCI_HOST_CONTROL);
220
			data &= ~ESDHC_CTRL_D3CD;
221
			writel(data, host->ioaddr + SDHCI_HOST_CONTROL);
222
			data |= ESDHC_CTRL_D3CD;
223 224 225
			writel(data, host->ioaddr + SDHCI_HOST_CONTROL);
		}
	}
226

227 228 229 230
	if (unlikely((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
				&& (reg == SDHCI_INT_STATUS)
				&& (val & SDHCI_INT_DATA_END))) {
			u32 v;
231 232 233
			v = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
			v &= ~ESDHC_VENDOR_SPEC_SDIO_QUIRK;
			writel(v, host->ioaddr + ESDHC_VENDOR_SPEC);
234 235 236 237 238 239 240 241 242

			if (imx_data->multiblock_status == MULTIBLK_IN_PROCESS)
			{
				/* send a manual CMD12 with RESPTYP=none */
				data = MMC_STOP_TRANSMISSION << 24 |
				       SDHCI_CMD_ABORTCMD << 16;
				writel(data, host->ioaddr + SDHCI_TRANSFER_MODE);
				imx_data->multiblock_status = WAIT_FOR_INT;
			}
243 244
	}

R
Richard Zhu 已提交
245 246 247
	if (unlikely(reg == SDHCI_INT_ENABLE || reg == SDHCI_SIGNAL_ENABLE)) {
		if (val & SDHCI_INT_ADMA_ERROR) {
			val &= ~SDHCI_INT_ADMA_ERROR;
248
			val |= ESDHC_INT_VENDOR_SPEC_DMA_ERR;
R
Richard Zhu 已提交
249 250 251
		}
	}

252 253 254
	writel(val, host->ioaddr + reg);
}

255 256
static u16 esdhc_readw_le(struct sdhci_host *host, int reg)
{
257 258 259
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct pltfm_imx_data *imx_data = pltfm_host->priv;

260
	if (unlikely(reg == SDHCI_HOST_VERSION)) {
261 262 263 264 265 266 267 268
		reg ^= 2;
		if (is_imx6q_usdhc(imx_data)) {
			/*
			 * The usdhc register returns a wrong host version.
			 * Correct it here.
			 */
			return SDHCI_SPEC_300;
		}
269
	}
270 271 272 273 274 275 276

	return readw(host->ioaddr + reg);
}

static void esdhc_writew_le(struct sdhci_host *host, u16 val, int reg)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
277
	struct pltfm_imx_data *imx_data = pltfm_host->priv;
278 279 280

	switch (reg) {
	case SDHCI_TRANSFER_MODE:
281 282 283 284 285
		if ((imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT)
				&& (host->cmd->opcode == SD_IO_RW_EXTENDED)
				&& (host->cmd->data->blocks > 1)
				&& (host->cmd->data->flags & MMC_DATA_READ)) {
			u32 v;
286 287 288
			v = readl(host->ioaddr + ESDHC_VENDOR_SPEC);
			v |= ESDHC_VENDOR_SPEC_SDIO_QUIRK;
			writel(v, host->ioaddr + ESDHC_VENDOR_SPEC);
289
		}
290 291 292

		if (is_imx6q_usdhc(imx_data)) {
			u32 m = readl(host->ioaddr + ESDHC_MIX_CTRL);
293 294 295 296 297 298
			/* Swap AC23 bit */
			if (val & SDHCI_TRNS_AUTO_CMD23) {
				val &= ~SDHCI_TRNS_AUTO_CMD23;
				val |= ESDHC_MIX_CTRL_AC23EN;
			}
			m = val | (m & ~ESDHC_MIX_CTRL_SDHCI_MASK);
299 300 301 302 303 304 305 306
			writel(m, host->ioaddr + ESDHC_MIX_CTRL);
		} else {
			/*
			 * Postpone this write, we must do it together with a
			 * command write that is down below.
			 */
			imx_data->scratchpad = val;
		}
307 308
		return;
	case SDHCI_COMMAND:
309
		if (host->cmd->opcode == MMC_STOP_TRANSMISSION)
310
			val |= SDHCI_CMD_ABORTCMD;
311

312 313 314 315
		if ((host->cmd->opcode == MMC_SET_BLOCK_COUNT) &&
		    (imx_data->flags & ESDHC_FLAG_MULTIBLK_NO_INT))
			imx_data->multiblock_status = MULTIBLK_IN_PROCESS;

316
		if (is_imx6q_usdhc(imx_data))
317 318
			writel(val << 16,
			       host->ioaddr + SDHCI_TRANSFER_MODE);
319
		else
320 321
			writel(val << 16 | imx_data->scratchpad,
			       host->ioaddr + SDHCI_TRANSFER_MODE);
322 323 324 325 326 327 328 329 330 331
		return;
	case SDHCI_BLOCK_SIZE:
		val &= ~SDHCI_MAKE_BLKSZ(0x7, 0);
		break;
	}
	esdhc_clrset_le(host, 0xffff, val, reg);
}

static void esdhc_writeb_le(struct sdhci_host *host, u8 val, int reg)
{
332 333
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct pltfm_imx_data *imx_data = pltfm_host->priv;
334
	u32 new_val;
335
	u32 mask;
336 337 338 339 340 341 342 343 344

	switch (reg) {
	case SDHCI_POWER_CONTROL:
		/*
		 * FSL put some DMA bits here
		 * If your board has a regulator, code should be here
		 */
		return;
	case SDHCI_HOST_CONTROL:
345
		/* FSL messed up here, so we need to manually compose it. */
346
		new_val = val & SDHCI_CTRL_LED;
M
Masanari Iida 已提交
347
		/* ensure the endianness */
348
		new_val |= ESDHC_HOST_CONTROL_LE;
349 350 351 352 353
		/* bits 8&9 are reserved on mx25 */
		if (!is_imx25_esdhc(imx_data)) {
			/* DMA mode bits are shifted */
			new_val |= (val & SDHCI_CTRL_DMA_MASK) << 5;
		}
354

355 356 357
		/*
		 * Do not touch buswidth bits here. This is done in
		 * esdhc_pltfm_bus_width.
358 359
		 * Do not touch the D3CD bit either which is used for the
		 * SDIO interrupt errata workaround.
360
		 */
361
		mask = 0xffff & ~(ESDHC_CTRL_BUSWIDTH_MASK | ESDHC_CTRL_D3CD);
362 363

		esdhc_clrset_le(host, mask, new_val, reg);
364 365 366
		return;
	}
	esdhc_clrset_le(host, 0xff, val, reg);
367 368 369 370 371 372 373 374 375

	/*
	 * The esdhc has a design violation to SDHC spec which tells
	 * that software reset should not affect card detection circuit.
	 * But esdhc clears its SYSCTL register bits [0..2] during the
	 * software reset.  This will stop those clocks that card detection
	 * circuit relies on.  To work around it, we turn the clocks on back
	 * to keep card detection circuit functional.
	 */
376
	if ((reg == SDHCI_SOFTWARE_RESET) && (val & 1)) {
377
		esdhc_clrset_le(host, 0x7, 0x7, ESDHC_SYSTEM_CONTROL);
378 379 380 381 382 383 384
		/*
		 * The reset on usdhc fails to clear MIX_CTRL register.
		 * Do it manually here.
		 */
		if (is_imx6q_usdhc(imx_data))
			writel(0, host->ioaddr + ESDHC_MIX_CTRL);
	}
385 386
}

387 388 389 390 391 392 393 394 395 396 397 398 399 400
static unsigned int esdhc_pltfm_get_max_clock(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct pltfm_imx_data *imx_data = pltfm_host->priv;
	struct esdhc_platform_data *boarddata = &imx_data->boarddata;

	u32 f_host = clk_get_rate(pltfm_host->clk);

	if (boarddata->f_max && (boarddata->f_max < f_host))
		return boarddata->f_max;
	else
		return f_host;
}

401 402 403 404 405 406 407
static unsigned int esdhc_pltfm_get_min_clock(struct sdhci_host *host)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);

	return clk_get_rate(pltfm_host->clk) / 256 / 16;
}

408 409 410 411
static inline void esdhc_pltfm_set_clock(struct sdhci_host *host,
					 unsigned int clock)
{
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444
	unsigned int host_clock = clk_get_rate(pltfm_host->clk);
	int pre_div = 2;
	int div = 1;
	u32 temp;

	if (clock == 0)
		goto out;

	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
	temp &= ~(ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
		| ESDHC_CLOCK_MASK);
	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);

	while (host_clock / pre_div / 16 > clock && pre_div < 256)
		pre_div *= 2;

	while (host_clock / pre_div / div > clock && div < 16)
		div++;

	dev_dbg(mmc_dev(host->mmc), "desired SD clock: %d, actual: %d\n",
		clock, host_clock / pre_div / div);

	pre_div >>= 1;
	div--;

	temp = sdhci_readl(host, ESDHC_SYSTEM_CONTROL);
	temp |= (ESDHC_CLOCK_IPGEN | ESDHC_CLOCK_HCKEN | ESDHC_CLOCK_PEREN
		| (div << ESDHC_DIVIDER_SHIFT)
		| (pre_div << ESDHC_PREDIV_SHIFT));
	sdhci_writel(host, temp, ESDHC_SYSTEM_CONTROL);
	mdelay(1);
out:
	host->clock = clock;
445 446
}

447 448
static unsigned int esdhc_pltfm_get_ro(struct sdhci_host *host)
{
449 450 451
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
	struct pltfm_imx_data *imx_data = pltfm_host->priv;
	struct esdhc_platform_data *boarddata = &imx_data->boarddata;
452 453 454

	switch (boarddata->wp_type) {
	case ESDHC_WP_GPIO:
455
		return mmc_gpio_get_ro(host->mmc);
456 457 458 459 460 461 462 463 464 465
	case ESDHC_WP_CONTROLLER:
		return !(readl(host->ioaddr + SDHCI_PRESENT_STATE) &
			       SDHCI_WRITE_PROTECT);
	case ESDHC_WP_NONE:
		break;
	}

	return -ENOSYS;
}

466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487
static int esdhc_pltfm_bus_width(struct sdhci_host *host, int width)
{
	u32 ctrl;

	switch (width) {
	case MMC_BUS_WIDTH_8:
		ctrl = ESDHC_CTRL_8BITBUS;
		break;
	case MMC_BUS_WIDTH_4:
		ctrl = ESDHC_CTRL_4BITBUS;
		break;
	default:
		ctrl = 0;
		break;
	}

	esdhc_clrset_le(host, ESDHC_CTRL_BUSWIDTH_MASK, ctrl,
			SDHCI_HOST_CONTROL);

	return 0;
}

488
static const struct sdhci_ops sdhci_esdhc_ops = {
489
	.read_l = esdhc_readl_le,
490
	.read_w = esdhc_readw_le,
491
	.write_l = esdhc_writel_le,
492 493
	.write_w = esdhc_writew_le,
	.write_b = esdhc_writeb_le,
494
	.set_clock = esdhc_pltfm_set_clock,
495
	.get_max_clock = esdhc_pltfm_get_max_clock,
496
	.get_min_clock = esdhc_pltfm_get_min_clock,
497
	.get_ro = esdhc_pltfm_get_ro,
498
	.platform_bus_width = esdhc_pltfm_bus_width,
499 500
};

501
static const struct sdhci_pltfm_data sdhci_esdhc_imx_pdata = {
R
Richard Zhu 已提交
502 503 504
	.quirks = ESDHC_DEFAULT_QUIRKS | SDHCI_QUIRK_NO_HISPD_BIT
			| SDHCI_QUIRK_NO_ENDATTR_IN_NOPDESC
			| SDHCI_QUIRK_BROKEN_ADMA_ZEROLEN_DESC
505 506 507 508
			| SDHCI_QUIRK_BROKEN_CARD_DETECTION,
	.ops = &sdhci_esdhc_ops,
};

509
#ifdef CONFIG_OF
B
Bill Pemberton 已提交
510
static int
511 512 513 514 515 516 517 518
sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
			 struct esdhc_platform_data *boarddata)
{
	struct device_node *np = pdev->dev.of_node;

	if (!np)
		return -ENODEV;

A
Arnd Bergmann 已提交
519
	if (of_get_property(np, "non-removable", NULL))
520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535
		boarddata->cd_type = ESDHC_CD_PERMANENT;

	if (of_get_property(np, "fsl,cd-controller", NULL))
		boarddata->cd_type = ESDHC_CD_CONTROLLER;

	if (of_get_property(np, "fsl,wp-controller", NULL))
		boarddata->wp_type = ESDHC_WP_CONTROLLER;

	boarddata->cd_gpio = of_get_named_gpio(np, "cd-gpios", 0);
	if (gpio_is_valid(boarddata->cd_gpio))
		boarddata->cd_type = ESDHC_CD_GPIO;

	boarddata->wp_gpio = of_get_named_gpio(np, "wp-gpios", 0);
	if (gpio_is_valid(boarddata->wp_gpio))
		boarddata->wp_type = ESDHC_WP_GPIO;

536 537
	of_property_read_u32(np, "bus-width", &boarddata->max_bus_width);

538 539
	of_property_read_u32(np, "max-frequency", &boarddata->f_max);

540 541 542 543 544 545 546 547 548 549 550
	return 0;
}
#else
static inline int
sdhci_esdhc_imx_probe_dt(struct platform_device *pdev,
			 struct esdhc_platform_data *boarddata)
{
	return -ENODEV;
}
#endif

B
Bill Pemberton 已提交
551
static int sdhci_esdhc_imx_probe(struct platform_device *pdev)
552
{
553 554
	const struct of_device_id *of_id =
			of_match_device(imx_esdhc_dt_ids, &pdev->dev);
555 556 557
	struct sdhci_pltfm_host *pltfm_host;
	struct sdhci_host *host;
	struct esdhc_platform_data *boarddata;
558
	int err;
559
	struct pltfm_imx_data *imx_data;
560

561
	host = sdhci_pltfm_init(pdev, &sdhci_esdhc_imx_pdata, 0);
562 563 564 565 566
	if (IS_ERR(host))
		return PTR_ERR(host);

	pltfm_host = sdhci_priv(host);

567
	imx_data = devm_kzalloc(&pdev->dev, sizeof(*imx_data), GFP_KERNEL);
568 569
	if (!imx_data) {
		err = -ENOMEM;
570
		goto free_sdhci;
571
	}
572

573 574
	if (of_id)
		pdev->id_entry = of_id->data;
575
	imx_data->devtype = pdev->id_entry->driver_data;
576 577
	pltfm_host->priv = imx_data;

578 579 580
	imx_data->clk_ipg = devm_clk_get(&pdev->dev, "ipg");
	if (IS_ERR(imx_data->clk_ipg)) {
		err = PTR_ERR(imx_data->clk_ipg);
581
		goto free_sdhci;
582
	}
583 584 585 586

	imx_data->clk_ahb = devm_clk_get(&pdev->dev, "ahb");
	if (IS_ERR(imx_data->clk_ahb)) {
		err = PTR_ERR(imx_data->clk_ahb);
587
		goto free_sdhci;
588 589 590 591 592
	}

	imx_data->clk_per = devm_clk_get(&pdev->dev, "per");
	if (IS_ERR(imx_data->clk_per)) {
		err = PTR_ERR(imx_data->clk_per);
593
		goto free_sdhci;
594 595 596 597 598 599 600
	}

	pltfm_host->clk = imx_data->clk_per;

	clk_prepare_enable(imx_data->clk_per);
	clk_prepare_enable(imx_data->clk_ipg);
	clk_prepare_enable(imx_data->clk_ahb);
601

602 603 604
	imx_data->pinctrl = devm_pinctrl_get_select_default(&pdev->dev);
	if (IS_ERR(imx_data->pinctrl)) {
		err = PTR_ERR(imx_data->pinctrl);
605
		goto disable_clk;
606 607
	}

608
	host->quirks |= SDHCI_QUIRK_BROKEN_TIMEOUT_VAL;
609

610
	if (is_imx25_esdhc(imx_data) || is_imx35_esdhc(imx_data))
611
		/* Fix errata ENGcm07207 present on i.MX25 and i.MX35 */
R
Richard Zhu 已提交
612 613
		host->quirks |= SDHCI_QUIRK_NO_MULTIBLOCK
			| SDHCI_QUIRK_BROKEN_ADMA;
614

615
	if (is_imx53_esdhc(imx_data))
616 617
		imx_data->flags |= ESDHC_FLAG_MULTIBLK_NO_INT;

618 619 620 621 622
	/*
	 * The imx6q ROM code will change the default watermark level setting
	 * to something insane.  Change it back here.
	 */
	if (is_imx6q_usdhc(imx_data))
623
		writel(0x08100810, host->ioaddr + ESDHC_WTMK_LVL);
624

625
	boarddata = &imx_data->boarddata;
626 627 628 629
	if (sdhci_esdhc_imx_probe_dt(pdev, boarddata) < 0) {
		if (!host->mmc->parent->platform_data) {
			dev_err(mmc_dev(host->mmc), "no board data!\n");
			err = -EINVAL;
630
			goto disable_clk;
631 632 633 634
		}
		imx_data->boarddata = *((struct esdhc_platform_data *)
					host->mmc->parent->platform_data);
	}
635 636 637

	/* write_protect */
	if (boarddata->wp_type == ESDHC_WP_GPIO) {
638
		err = mmc_gpio_request_ro(host->mmc, boarddata->wp_gpio);
639
		if (err) {
640 641 642
			dev_err(mmc_dev(host->mmc),
				"failed to request write-protect gpio!\n");
			goto disable_clk;
643
		}
644
		host->mmc->caps2 |= MMC_CAP2_RO_ACTIVE_HIGH;
645 646 647 648 649
	}

	/* card_detect */
	switch (boarddata->cd_type) {
	case ESDHC_CD_GPIO:
650
		err = mmc_gpio_request_cd(host->mmc, boarddata->cd_gpio, 0);
651
		if (err) {
652
			dev_err(mmc_dev(host->mmc),
653
				"failed to request card-detect gpio!\n");
654
			goto disable_clk;
655
		}
656
		/* fall through */
657

658 659
	case ESDHC_CD_CONTROLLER:
		/* we have a working card_detect back */
660
		host->quirks &= ~SDHCI_QUIRK_BROKEN_CARD_DETECTION;
661 662 663 664 665 666 667 668
		break;

	case ESDHC_CD_PERMANENT:
		host->mmc->caps = MMC_CAP_NONREMOVABLE;
		break;

	case ESDHC_CD_NONE:
		break;
669
	}
670

671 672 673 674 675 676 677 678 679 680 681 682 683
	switch (boarddata->max_bus_width) {
	case 8:
		host->mmc->caps |= MMC_CAP_8_BIT_DATA | MMC_CAP_4_BIT_DATA;
		break;
	case 4:
		host->mmc->caps |= MMC_CAP_4_BIT_DATA;
		break;
	case 1:
	default:
		host->quirks |= SDHCI_QUIRK_FORCE_1_BIT_DATA;
		break;
	}

684 685
	err = sdhci_add_host(host);
	if (err)
686
		goto disable_clk;
687

688
	return 0;
689

690
disable_clk:
691 692 693
	clk_disable_unprepare(imx_data->clk_per);
	clk_disable_unprepare(imx_data->clk_ipg);
	clk_disable_unprepare(imx_data->clk_ahb);
694
free_sdhci:
695 696
	sdhci_pltfm_free(pdev);
	return err;
697 698
}

B
Bill Pemberton 已提交
699
static int sdhci_esdhc_imx_remove(struct platform_device *pdev)
700
{
701
	struct sdhci_host *host = platform_get_drvdata(pdev);
702
	struct sdhci_pltfm_host *pltfm_host = sdhci_priv(host);
703
	struct pltfm_imx_data *imx_data = pltfm_host->priv;
704 705 706
	int dead = (readl(host->ioaddr + SDHCI_INT_STATUS) == 0xffffffff);

	sdhci_remove_host(host, dead);
707

708 709 710 711
	clk_disable_unprepare(imx_data->clk_per);
	clk_disable_unprepare(imx_data->clk_ipg);
	clk_disable_unprepare(imx_data->clk_ahb);

712 713 714
	sdhci_pltfm_free(pdev);

	return 0;
715 716
}

717 718 719 720
static struct platform_driver sdhci_esdhc_imx_driver = {
	.driver		= {
		.name	= "sdhci-esdhc-imx",
		.owner	= THIS_MODULE,
721
		.of_match_table = imx_esdhc_dt_ids,
722
		.pm	= SDHCI_PLTFM_PMOPS,
723
	},
724
	.id_table	= imx_esdhc_devtype,
725
	.probe		= sdhci_esdhc_imx_probe,
B
Bill Pemberton 已提交
726
	.remove		= sdhci_esdhc_imx_remove,
727
};
728

729
module_platform_driver(sdhci_esdhc_imx_driver);
730 731 732 733

MODULE_DESCRIPTION("SDHCI driver for Freescale i.MX eSDHC");
MODULE_AUTHOR("Wolfram Sang <w.sang@pengutronix.de>");
MODULE_LICENSE("GPL v2");