omap.c 37.8 KB
Newer Older
C
Carlos Aguiar 已提交
1
/*
P
Pierre Ossman 已提交
2
 *  linux/drivers/mmc/host/omap.c
C
Carlos Aguiar 已提交
3 4
 *
 *  Copyright (C) 2004 Nokia Corporation
A
Al Viro 已提交
5
 *  Written by Tuukka Tikkanen and Juha Yrjölä<juha.yrjola@nokia.com>
C
Carlos Aguiar 已提交
6 7 8 9 10 11 12 13 14 15 16 17 18 19
 *  Misc hacks here and there by Tony Lindgren <tony@atomide.com>
 *  Other hacks (DMA, SD, etc) by David Brownell
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/module.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
#include <linux/ioport.h>
#include <linux/platform_device.h>
#include <linux/interrupt.h>
R
Russell King 已提交
20
#include <linux/dmaengine.h>
C
Carlos Aguiar 已提交
21 22 23 24
#include <linux/dma-mapping.h>
#include <linux/delay.h>
#include <linux/spinlock.h>
#include <linux/timer.h>
R
Russell King 已提交
25
#include <linux/omap-dma.h>
C
Carlos Aguiar 已提交
26 27 28
#include <linux/mmc/host.h>
#include <linux/mmc/card.h>
#include <linux/clk.h>
J
Jens Axboe 已提交
29
#include <linux/scatterlist.h>
30
#include <linux/i2c/tps65010.h>
31
#include <linux/slab.h>
C
Carlos Aguiar 已提交
32 33 34 35

#include <asm/io.h>
#include <asm/irq.h>

36 37
#include <plat/board.h>
#include <plat/mmc.h>
38
#include <asm/gpio.h>
39 40 41
#include <plat/dma.h>
#include <plat/mux.h>
#include <plat/fpga.h>
C
Carlos Aguiar 已提交
42

43
#define	OMAP_MMC_REG_CMD	0x00
44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
#define	OMAP_MMC_REG_ARGL	0x01
#define	OMAP_MMC_REG_ARGH	0x02
#define	OMAP_MMC_REG_CON	0x03
#define	OMAP_MMC_REG_STAT	0x04
#define	OMAP_MMC_REG_IE		0x05
#define	OMAP_MMC_REG_CTO	0x06
#define	OMAP_MMC_REG_DTO	0x07
#define	OMAP_MMC_REG_DATA	0x08
#define	OMAP_MMC_REG_BLEN	0x09
#define	OMAP_MMC_REG_NBLK	0x0a
#define	OMAP_MMC_REG_BUF	0x0b
#define	OMAP_MMC_REG_SDIO	0x0d
#define	OMAP_MMC_REG_REV	0x0f
#define	OMAP_MMC_REG_RSP0	0x10
#define	OMAP_MMC_REG_RSP1	0x11
#define	OMAP_MMC_REG_RSP2	0x12
#define	OMAP_MMC_REG_RSP3	0x13
#define	OMAP_MMC_REG_RSP4	0x14
#define	OMAP_MMC_REG_RSP5	0x15
#define	OMAP_MMC_REG_RSP6	0x16
#define	OMAP_MMC_REG_RSP7	0x17
#define	OMAP_MMC_REG_IOSR	0x18
#define	OMAP_MMC_REG_SYSC	0x19
#define	OMAP_MMC_REG_SYSS	0x1a
68 69 70 71 72 73 74 75 76 77 78 79 80 81 82

#define	OMAP_MMC_STAT_CARD_ERR		(1 << 14)
#define	OMAP_MMC_STAT_CARD_IRQ		(1 << 13)
#define	OMAP_MMC_STAT_OCR_BUSY		(1 << 12)
#define	OMAP_MMC_STAT_A_EMPTY		(1 << 11)
#define	OMAP_MMC_STAT_A_FULL		(1 << 10)
#define	OMAP_MMC_STAT_CMD_CRC		(1 <<  8)
#define	OMAP_MMC_STAT_CMD_TOUT		(1 <<  7)
#define	OMAP_MMC_STAT_DATA_CRC		(1 <<  6)
#define	OMAP_MMC_STAT_DATA_TOUT		(1 <<  5)
#define	OMAP_MMC_STAT_END_BUSY		(1 <<  4)
#define	OMAP_MMC_STAT_END_OF_DATA	(1 <<  3)
#define	OMAP_MMC_STAT_CARD_BUSY		(1 <<  2)
#define	OMAP_MMC_STAT_END_OF_CMD	(1 <<  0)

83 84 85
#define OMAP_MMC_REG(host, reg)		(OMAP_MMC_REG_##reg << (host)->reg_shift)
#define OMAP_MMC_READ(host, reg)	__raw_readw((host)->virt_base + OMAP_MMC_REG(host, reg))
#define OMAP_MMC_WRITE(host, reg, val)	__raw_writew((val), (host)->virt_base + OMAP_MMC_REG(host, reg))
86 87 88 89 90 91 92 93 94

/*
 * Command types
 */
#define OMAP_MMC_CMDTYPE_BC	0
#define OMAP_MMC_CMDTYPE_BCR	1
#define OMAP_MMC_CMDTYPE_AC	2
#define OMAP_MMC_CMDTYPE_ADTC	3

C
Carlos Aguiar 已提交
95 96 97 98 99

#define DRIVER_NAME "mmci-omap"

/* Specifies how often in millisecs to poll for card status changes
 * when the cover switch is open */
100
#define OMAP_MMC_COVER_POLL_DELAY	500
C
Carlos Aguiar 已提交
101

102 103 104 105 106 107 108 109 110 111
struct mmc_omap_host;

struct mmc_omap_slot {
	int			id;
	unsigned int		vdd;
	u16			saved_con;
	u16			bus_mode;
	unsigned int		fclk_freq;
	unsigned		powered:1;

112 113
	struct tasklet_struct	cover_tasklet;
	struct timer_list       cover_timer;
114 115
	unsigned		cover_open;

116 117 118 119 120 121
	struct mmc_request      *mrq;
	struct mmc_omap_host    *host;
	struct mmc_host		*mmc;
	struct omap_mmc_slot_data *pdata;
};

C
Carlos Aguiar 已提交
122 123 124 125 126 127 128 129 130 131 132
struct mmc_omap_host {
	int			initialized;
	int			suspended;
	struct mmc_request *	mrq;
	struct mmc_command *	cmd;
	struct mmc_data *	data;
	struct mmc_host *	mmc;
	struct device *		dev;
	unsigned char		id; /* 16xx chips have 2 MMC blocks */
	struct clk *		iclk;
	struct clk *		fclk;
R
Russell King 已提交
133 134 135 136
	struct dma_chan		*dma_rx;
	u32			dma_rx_burst;
	struct dma_chan		*dma_tx;
	u32			dma_tx_burst;
137 138 139
	struct resource		*mem_res;
	void __iomem		*virt_base;
	unsigned int		phys_base;
C
Carlos Aguiar 已提交
140 141 142
	int			irq;
	unsigned char		bus_mode;
	unsigned char		hw_bus_mode;
143
	unsigned int		reg_shift;
C
Carlos Aguiar 已提交
144

145 146 147
	struct work_struct	cmd_abort_work;
	unsigned		abort:1;
	struct timer_list	cmd_abort_timer;
J
Jarkko Lavinen 已提交
148

149 150 151 152 153
	struct work_struct      slot_release_work;
	struct mmc_omap_slot    *next_slot;
	struct work_struct      send_stop_work;
	struct mmc_data		*stop_data;

C
Carlos Aguiar 已提交
154 155 156 157 158 159 160 161 162
	unsigned int		sg_len;
	int			sg_idx;
	u16 *			buffer;
	u32			buffer_bytes_left;
	u32			total_bytes_left;

	unsigned		use_dma:1;
	unsigned		brs_received:1, dma_done:1;
	unsigned		dma_in_use:1;
R
Russell King 已提交
163
	spinlock_t		dma_lock;
C
Carlos Aguiar 已提交
164

165 166 167 168 169 170
	struct mmc_omap_slot    *slots[OMAP_MMC_MAX_SLOTS];
	struct mmc_omap_slot    *current_slot;
	spinlock_t              slot_lock;
	wait_queue_head_t       slot_wq;
	int                     nr_slots;

J
Jarkko Lavinen 已提交
171 172 173
	struct timer_list       clk_timer;
	spinlock_t		clk_lock;     /* for changing enabled state */
	unsigned int            fclk_enabled:1;
174
	struct workqueue_struct *mmc_omap_wq;
J
Jarkko Lavinen 已提交
175

176
	struct omap_mmc_platform_data *pdata;
C
Carlos Aguiar 已提交
177 178
};

T
Tejun Heo 已提交
179

180
static void mmc_omap_fclk_offdelay(struct mmc_omap_slot *slot)
J
Jarkko Lavinen 已提交
181 182 183 184 185 186 187 188 189
{
	unsigned long tick_ns;

	if (slot != NULL && slot->host->fclk_enabled && slot->fclk_freq > 0) {
		tick_ns = (1000000000 + slot->fclk_freq - 1) / slot->fclk_freq;
		ndelay(8 * tick_ns);
	}
}

190
static void mmc_omap_fclk_enable(struct mmc_omap_host *host, unsigned int enable)
J
Jarkko Lavinen 已提交
191 192 193 194 195 196 197 198 199 200 201 202 203 204
{
	unsigned long flags;

	spin_lock_irqsave(&host->clk_lock, flags);
	if (host->fclk_enabled != enable) {
		host->fclk_enabled = enable;
		if (enable)
			clk_enable(host->fclk);
		else
			clk_disable(host->fclk);
	}
	spin_unlock_irqrestore(&host->clk_lock, flags);
}

205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220
static void mmc_omap_select_slot(struct mmc_omap_slot *slot, int claimed)
{
	struct mmc_omap_host *host = slot->host;
	unsigned long flags;

	if (claimed)
		goto no_claim;
	spin_lock_irqsave(&host->slot_lock, flags);
	while (host->mmc != NULL) {
		spin_unlock_irqrestore(&host->slot_lock, flags);
		wait_event(host->slot_wq, host->mmc == NULL);
		spin_lock_irqsave(&host->slot_lock, flags);
	}
	host->mmc = slot->mmc;
	spin_unlock_irqrestore(&host->slot_lock, flags);
no_claim:
J
Jarkko Lavinen 已提交
221 222 223 224
	del_timer(&host->clk_timer);
	if (host->current_slot != slot || !claimed)
		mmc_omap_fclk_offdelay(host->current_slot);

225
	if (host->current_slot != slot) {
J
Jarkko Lavinen 已提交
226
		OMAP_MMC_WRITE(host, CON, slot->saved_con & 0xFC00);
227 228 229 230 231
		if (host->pdata->switch_slot != NULL)
			host->pdata->switch_slot(mmc_dev(slot->mmc), slot->id);
		host->current_slot = slot;
	}

J
Jarkko Lavinen 已提交
232 233 234 235 236 237 238
	if (claimed) {
		mmc_omap_fclk_enable(host, 1);

		/* Doing the dummy read here seems to work around some bug
		 * at least in OMAP24xx silicon where the command would not
		 * start after writing the CMD register. Sigh. */
		OMAP_MMC_READ(host, CON);
239

J
Jarkko Lavinen 已提交
240 241 242
		OMAP_MMC_WRITE(host, CON, slot->saved_con);
	} else
		mmc_omap_fclk_enable(host, 0);
243 244 245 246 247
}

static void mmc_omap_start_request(struct mmc_omap_host *host,
				   struct mmc_request *req);

248 249 250 251 252 253 254 255 256 257 258 259 260 261 262
static void mmc_omap_slot_release_work(struct work_struct *work)
{
	struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
						  slot_release_work);
	struct mmc_omap_slot *next_slot = host->next_slot;
	struct mmc_request *rq;

	host->next_slot = NULL;
	mmc_omap_select_slot(next_slot, 1);

	rq = next_slot->mrq;
	next_slot->mrq = NULL;
	mmc_omap_start_request(host, rq);
}

J
Jarkko Lavinen 已提交
263
static void mmc_omap_release_slot(struct mmc_omap_slot *slot, int clk_enabled)
264 265 266 267 268 269
{
	struct mmc_omap_host *host = slot->host;
	unsigned long flags;
	int i;

	BUG_ON(slot == NULL || host->mmc == NULL);
J
Jarkko Lavinen 已提交
270 271 272 273 274 275 276 277 278

	if (clk_enabled)
		/* Keeps clock running for at least 8 cycles on valid freq */
		mod_timer(&host->clk_timer, jiffies  + HZ/10);
	else {
		del_timer(&host->clk_timer);
		mmc_omap_fclk_offdelay(slot);
		mmc_omap_fclk_enable(host, 0);
	}
279 280 281 282 283 284 285 286 287

	spin_lock_irqsave(&host->slot_lock, flags);
	/* Check for any pending requests */
	for (i = 0; i < host->nr_slots; i++) {
		struct mmc_omap_slot *new_slot;

		if (host->slots[i] == NULL || host->slots[i]->mrq == NULL)
			continue;

288
		BUG_ON(host->next_slot != NULL);
289 290 291 292
		new_slot = host->slots[i];
		/* The current slot should not have a request in queue */
		BUG_ON(new_slot == host->current_slot);

293
		host->next_slot = new_slot;
294 295
		host->mmc = new_slot->mmc;
		spin_unlock_irqrestore(&host->slot_lock, flags);
296
		queue_work(host->mmc_omap_wq, &host->slot_release_work);
297 298 299 300 301 302 303 304
		return;
	}

	host->mmc = NULL;
	wake_up(&host->slot_wq);
	spin_unlock_irqrestore(&host->slot_lock, flags);
}

305 306 307
static inline
int mmc_omap_cover_is_open(struct mmc_omap_slot *slot)
{
308 309 310 311
	if (slot->pdata->get_cover_state)
		return slot->pdata->get_cover_state(mmc_dev(slot->mmc),
						    slot->id);
	return 0;
312 313 314 315 316 317 318 319 320 321 322 323 324 325 326
}

static ssize_t
mmc_omap_show_cover_switch(struct device *dev, struct device_attribute *attr,
			   char *buf)
{
	struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
	struct mmc_omap_slot *slot = mmc_priv(mmc);

	return sprintf(buf, "%s\n", mmc_omap_cover_is_open(slot) ? "open" :
		       "closed");
}

static DEVICE_ATTR(cover_switch, S_IRUGO, mmc_omap_show_cover_switch, NULL);

327 328 329 330 331 332 333 334 335 336 337 338
static ssize_t
mmc_omap_show_slot_name(struct device *dev, struct device_attribute *attr,
			char *buf)
{
	struct mmc_host *mmc = container_of(dev, struct mmc_host, class_dev);
	struct mmc_omap_slot *slot = mmc_priv(mmc);

	return sprintf(buf, "%s\n", slot->pdata->name);
}

static DEVICE_ATTR(slot_name, S_IRUGO, mmc_omap_show_slot_name, NULL);

C
Carlos Aguiar 已提交
339 340 341 342 343 344 345 346 347 348 349 350 351
static void
mmc_omap_start_command(struct mmc_omap_host *host, struct mmc_command *cmd)
{
	u32 cmdreg;
	u32 resptype;
	u32 cmdtype;

	host->cmd = cmd;

	resptype = 0;
	cmdtype = 0;

	/* Our hardware needs to know exact type */
352 353 354 355 356
	switch (mmc_resp_type(cmd)) {
	case MMC_RSP_NONE:
		break;
	case MMC_RSP_R1:
	case MMC_RSP_R1B:
P
Philip Langdale 已提交
357
		/* resp 1, 1b, 6, 7 */
C
Carlos Aguiar 已提交
358 359
		resptype = 1;
		break;
360
	case MMC_RSP_R2:
C
Carlos Aguiar 已提交
361 362
		resptype = 2;
		break;
363
	case MMC_RSP_R3:
C
Carlos Aguiar 已提交
364 365 366
		resptype = 3;
		break;
	default:
367
		dev_err(mmc_dev(host->mmc), "Invalid response type: %04x\n", mmc_resp_type(cmd));
C
Carlos Aguiar 已提交
368 369 370 371 372 373 374 375 376 377 378 379 380 381 382
		break;
	}

	if (mmc_cmd_type(cmd) == MMC_CMD_ADTC) {
		cmdtype = OMAP_MMC_CMDTYPE_ADTC;
	} else if (mmc_cmd_type(cmd) == MMC_CMD_BC) {
		cmdtype = OMAP_MMC_CMDTYPE_BC;
	} else if (mmc_cmd_type(cmd) == MMC_CMD_BCR) {
		cmdtype = OMAP_MMC_CMDTYPE_BCR;
	} else {
		cmdtype = OMAP_MMC_CMDTYPE_AC;
	}

	cmdreg = cmd->opcode | (resptype << 8) | (cmdtype << 12);

383
	if (host->current_slot->bus_mode == MMC_BUSMODE_OPENDRAIN)
C
Carlos Aguiar 已提交
384 385 386 387 388 389 390 391
		cmdreg |= 1 << 6;

	if (cmd->flags & MMC_RSP_BUSY)
		cmdreg |= 1 << 11;

	if (host->data && !(host->data->flags & MMC_DATA_WRITE))
		cmdreg |= 1 << 15;

392
	mod_timer(&host->cmd_abort_timer, jiffies + HZ/2);
J
Jarkko Lavinen 已提交
393

394 395 396 397
	OMAP_MMC_WRITE(host, CTO, 200);
	OMAP_MMC_WRITE(host, ARGL, cmd->arg & 0xffff);
	OMAP_MMC_WRITE(host, ARGH, cmd->arg >> 16);
	OMAP_MMC_WRITE(host, IE,
C
Carlos Aguiar 已提交
398 399 400 401 402
		       OMAP_MMC_STAT_A_EMPTY    | OMAP_MMC_STAT_A_FULL    |
		       OMAP_MMC_STAT_CMD_CRC    | OMAP_MMC_STAT_CMD_TOUT  |
		       OMAP_MMC_STAT_DATA_CRC   | OMAP_MMC_STAT_DATA_TOUT |
		       OMAP_MMC_STAT_END_OF_CMD | OMAP_MMC_STAT_CARD_ERR  |
		       OMAP_MMC_STAT_END_OF_DATA);
403
	OMAP_MMC_WRITE(host, CMD, cmdreg);
C
Carlos Aguiar 已提交
404 405
}

406 407 408 409 410
static void
mmc_omap_release_dma(struct mmc_omap_host *host, struct mmc_data *data,
		     int abort)
{
	enum dma_data_direction dma_data_dir;
R
Russell King 已提交
411 412
	struct device *dev = mmc_dev(host->mmc);
	struct dma_chan *c;
413

R
Russell King 已提交
414
	if (data->flags & MMC_DATA_WRITE) {
415
		dma_data_dir = DMA_TO_DEVICE;
R
Russell King 已提交
416 417
		c = host->dma_tx;
	} else {
418
		dma_data_dir = DMA_FROM_DEVICE;
R
Russell King 已提交
419 420 421 422 423 424 425 426 427 428 429
		c = host->dma_rx;
	}
	if (c) {
		if (data->error) {
			dmaengine_terminate_all(c);
			/* Claim nothing transferred on error... */
			data->bytes_xfered = 0;
		}
		dev = c->device->dev;
	}
	dma_unmap_sg(dev, data->sg, host->sg_len, dma_data_dir);
430 431
}

432 433 434 435 436 437 438 439 440 441 442 443 444 445
static void mmc_omap_send_stop_work(struct work_struct *work)
{
	struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
						  send_stop_work);
	struct mmc_omap_slot *slot = host->current_slot;
	struct mmc_data *data = host->stop_data;
	unsigned long tick_ns;

	tick_ns = (1000000000 + slot->fclk_freq - 1)/slot->fclk_freq;
	ndelay(8*tick_ns);

	mmc_omap_start_command(host, data->stop);
}

C
Carlos Aguiar 已提交
446 447 448
static void
mmc_omap_xfer_done(struct mmc_omap_host *host, struct mmc_data *data)
{
449 450 451
	if (host->dma_in_use)
		mmc_omap_release_dma(host, data, data->error);

C
Carlos Aguiar 已提交
452 453 454 455 456 457 458 459 460
	host->data = NULL;
	host->sg_len = 0;

	/* NOTE:  MMC layer will sometimes poll-wait CMD13 next, issuing
	 * dozens of requests until the card finishes writing data.
	 * It'd be cheaper to just wait till an EOFB interrupt arrives...
	 */

	if (!data->stop) {
461 462
		struct mmc_host *mmc;

C
Carlos Aguiar 已提交
463
		host->mrq = NULL;
464
		mmc = host->mmc;
J
Jarkko Lavinen 已提交
465
		mmc_omap_release_slot(host->current_slot, 1);
466
		mmc_request_done(mmc, data->mrq);
C
Carlos Aguiar 已提交
467 468 469
		return;
	}

470
	host->stop_data = data;
471
	queue_work(host->mmc_omap_wq, &host->send_stop_work);
C
Carlos Aguiar 已提交
472 473
}

J
Jarkko Lavinen 已提交
474
static void
475
mmc_omap_send_abort(struct mmc_omap_host *host, int maxloops)
J
Jarkko Lavinen 已提交
476 477 478 479 480 481 482 483
{
	struct mmc_omap_slot *slot = host->current_slot;
	unsigned int restarts, passes, timeout;
	u16 stat = 0;

	/* Sending abort takes 80 clocks. Have some extra and round up */
	timeout = (120*1000000 + slot->fclk_freq - 1)/slot->fclk_freq;
	restarts = 0;
484
	while (restarts < maxloops) {
J
Jarkko Lavinen 已提交
485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502
		OMAP_MMC_WRITE(host, STAT, 0xFFFF);
		OMAP_MMC_WRITE(host, CMD, (3 << 12) | (1 << 7));

		passes = 0;
		while (passes < timeout) {
			stat = OMAP_MMC_READ(host, STAT);
			if (stat & OMAP_MMC_STAT_END_OF_CMD)
				goto out;
			udelay(1);
			passes++;
		}

		restarts++;
	}
out:
	OMAP_MMC_WRITE(host, STAT, stat);
}

503 504 505 506 507 508 509 510 511
static void
mmc_omap_abort_xfer(struct mmc_omap_host *host, struct mmc_data *data)
{
	if (host->dma_in_use)
		mmc_omap_release_dma(host, data, 1);

	host->data = NULL;
	host->sg_len = 0;

512
	mmc_omap_send_abort(host, 10000);
513 514
}

C
Carlos Aguiar 已提交
515 516 517 518 519 520 521 522 523 524 525 526 527 528 529 530 531 532 533 534 535 536 537 538 539 540 541 542 543 544 545 546 547 548 549 550 551 552 553 554 555 556 557
static void
mmc_omap_end_of_data(struct mmc_omap_host *host, struct mmc_data *data)
{
	unsigned long flags;
	int done;

	if (!host->dma_in_use) {
		mmc_omap_xfer_done(host, data);
		return;
	}
	done = 0;
	spin_lock_irqsave(&host->dma_lock, flags);
	if (host->dma_done)
		done = 1;
	else
		host->brs_received = 1;
	spin_unlock_irqrestore(&host->dma_lock, flags);
	if (done)
		mmc_omap_xfer_done(host, data);
}

static void
mmc_omap_dma_done(struct mmc_omap_host *host, struct mmc_data *data)
{
	unsigned long flags;
	int done;

	done = 0;
	spin_lock_irqsave(&host->dma_lock, flags);
	if (host->brs_received)
		done = 1;
	else
		host->dma_done = 1;
	spin_unlock_irqrestore(&host->dma_lock, flags);
	if (done)
		mmc_omap_xfer_done(host, data);
}

static void
mmc_omap_cmd_done(struct mmc_omap_host *host, struct mmc_command *cmd)
{
	host->cmd = NULL;

558
	del_timer(&host->cmd_abort_timer);
J
Jarkko Lavinen 已提交
559

C
Carlos Aguiar 已提交
560 561 562 563
	if (cmd->flags & MMC_RSP_PRESENT) {
		if (cmd->flags & MMC_RSP_136) {
			/* response type 2 */
			cmd->resp[3] =
564 565
				OMAP_MMC_READ(host, RSP0) |
				(OMAP_MMC_READ(host, RSP1) << 16);
C
Carlos Aguiar 已提交
566
			cmd->resp[2] =
567 568
				OMAP_MMC_READ(host, RSP2) |
				(OMAP_MMC_READ(host, RSP3) << 16);
C
Carlos Aguiar 已提交
569
			cmd->resp[1] =
570 571
				OMAP_MMC_READ(host, RSP4) |
				(OMAP_MMC_READ(host, RSP5) << 16);
C
Carlos Aguiar 已提交
572
			cmd->resp[0] =
573 574
				OMAP_MMC_READ(host, RSP6) |
				(OMAP_MMC_READ(host, RSP7) << 16);
C
Carlos Aguiar 已提交
575 576 577
		} else {
			/* response types 1, 1b, 3, 4, 5, 6 */
			cmd->resp[0] =
578 579
				OMAP_MMC_READ(host, RSP6) |
				(OMAP_MMC_READ(host, RSP7) << 16);
C
Carlos Aguiar 已提交
580 581 582
		}
	}

P
Pierre Ossman 已提交
583
	if (host->data == NULL || cmd->error) {
584 585 586 587
		struct mmc_host *mmc;

		if (host->data != NULL)
			mmc_omap_abort_xfer(host, host->data);
C
Carlos Aguiar 已提交
588
		host->mrq = NULL;
589
		mmc = host->mmc;
J
Jarkko Lavinen 已提交
590
		mmc_omap_release_slot(host->current_slot, 1);
591
		mmc_request_done(mmc, cmd->mrq);
C
Carlos Aguiar 已提交
592 593 594
	}
}

J
Jarkko Lavinen 已提交
595 596 597 598 599 600 601
/*
 * Abort stuck command. Can occur when card is removed while it is being
 * read.
 */
static void mmc_omap_abort_command(struct work_struct *work)
{
	struct mmc_omap_host *host = container_of(work, struct mmc_omap_host,
602 603
						  cmd_abort_work);
	BUG_ON(!host->cmd);
J
Jarkko Lavinen 已提交
604 605 606 607

	dev_dbg(mmc_dev(host->mmc), "Aborting stuck command CMD%d\n",
		host->cmd->opcode);

608 609
	if (host->cmd->error == 0)
		host->cmd->error = -ETIMEDOUT;
J
Jarkko Lavinen 已提交
610

611 612 613 614 615 616 617 618 619 620
	if (host->data == NULL) {
		struct mmc_command *cmd;
		struct mmc_host    *mmc;

		cmd = host->cmd;
		host->cmd = NULL;
		mmc_omap_send_abort(host, 10000);

		host->mrq = NULL;
		mmc = host->mmc;
J
Jarkko Lavinen 已提交
621
		mmc_omap_release_slot(host->current_slot, 1);
622 623 624
		mmc_request_done(mmc, cmd->mrq);
	} else
		mmc_omap_cmd_done(host, host->cmd);
J
Jarkko Lavinen 已提交
625

626 627
	host->abort = 0;
	enable_irq(host->irq);
J
Jarkko Lavinen 已提交
628 629 630 631 632 633
}

static void
mmc_omap_cmd_timer(unsigned long data)
{
	struct mmc_omap_host *host = (struct mmc_omap_host *) data;
634
	unsigned long flags;
J
Jarkko Lavinen 已提交
635

636 637 638 639 640
	spin_lock_irqsave(&host->slot_lock, flags);
	if (host->cmd != NULL && !host->abort) {
		OMAP_MMC_WRITE(host, IE, 0);
		disable_irq(host->irq);
		host->abort = 1;
641
		queue_work(host->mmc_omap_wq, &host->cmd_abort_work);
642 643
	}
	spin_unlock_irqrestore(&host->slot_lock, flags);
J
Jarkko Lavinen 已提交
644 645
}

C
Carlos Aguiar 已提交
646 647 648 649 650 651 652 653
/* PIO only */
static void
mmc_omap_sg_to_buf(struct mmc_omap_host *host)
{
	struct scatterlist *sg;

	sg = host->data->sg + host->sg_idx;
	host->buffer_bytes_left = sg->length;
J
Jens Axboe 已提交
654
	host->buffer = sg_virt(sg);
C
Carlos Aguiar 已提交
655 656 657 658
	if (host->buffer_bytes_left > host->total_bytes_left)
		host->buffer_bytes_left = host->total_bytes_left;
}

J
Jarkko Lavinen 已提交
659 660 661 662 663 664 665 666
static void
mmc_omap_clk_timer(unsigned long data)
{
	struct mmc_omap_host *host = (struct mmc_omap_host *) data;

	mmc_omap_fclk_enable(host, 0);
}

C
Carlos Aguiar 已提交
667 668 669 670 671 672 673 674 675 676 677 678 679 680 681 682 683 684 685
/* PIO only */
static void
mmc_omap_xfer_data(struct mmc_omap_host *host, int write)
{
	int n;

	if (host->buffer_bytes_left == 0) {
		host->sg_idx++;
		BUG_ON(host->sg_idx == host->sg_len);
		mmc_omap_sg_to_buf(host);
	}
	n = 64;
	if (n > host->buffer_bytes_left)
		n = host->buffer_bytes_left;
	host->buffer_bytes_left -= n;
	host->total_bytes_left -= n;
	host->data->bytes_xfered += n;

	if (write) {
686
		__raw_writesw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n);
C
Carlos Aguiar 已提交
687
	} else {
688
		__raw_readsw(host->virt_base + OMAP_MMC_REG(host, DATA), host->buffer, n);
C
Carlos Aguiar 已提交
689 690 691 692 693 694 695 696 697 698 699 700 701 702 703 704 705 706 707 708
	}
}

static inline void mmc_omap_report_irq(u16 status)
{
	static const char *mmc_omap_status_bits[] = {
		"EOC", "CD", "CB", "BRS", "EOFB", "DTO", "DCRC", "CTO",
		"CCRC", "CRW", "AF", "AE", "OCRB", "CIRQ", "CERR"
	};
	int i, c = 0;

	for (i = 0; i < ARRAY_SIZE(mmc_omap_status_bits); i++)
		if (status & (1 << i)) {
			if (c)
				printk(" ");
			printk("%s", mmc_omap_status_bits[i]);
			c++;
		}
}

709
static irqreturn_t mmc_omap_irq(int irq, void *dev_id)
C
Carlos Aguiar 已提交
710 711 712 713 714
{
	struct mmc_omap_host * host = (struct mmc_omap_host *)dev_id;
	u16 status;
	int end_command;
	int end_transfer;
715
	int transfer_error, cmd_error;
C
Carlos Aguiar 已提交
716 717

	if (host->cmd == NULL && host->data == NULL) {
718
		status = OMAP_MMC_READ(host, STAT);
719 720
		dev_info(mmc_dev(host->slots[0]->mmc),
			 "Spurious IRQ 0x%04x\n", status);
C
Carlos Aguiar 已提交
721
		if (status != 0) {
722 723
			OMAP_MMC_WRITE(host, STAT, status);
			OMAP_MMC_WRITE(host, IE, 0);
C
Carlos Aguiar 已提交
724 725 726 727 728 729 730
		}
		return IRQ_HANDLED;
	}

	end_command = 0;
	end_transfer = 0;
	transfer_error = 0;
731
	cmd_error = 0;
C
Carlos Aguiar 已提交
732

733
	while ((status = OMAP_MMC_READ(host, STAT)) != 0) {
734 735
		int cmd;

736
		OMAP_MMC_WRITE(host, STAT, status);
737 738 739 740
		if (host->cmd != NULL)
			cmd = host->cmd->opcode;
		else
			cmd = -1;
C
Carlos Aguiar 已提交
741 742
#ifdef CONFIG_MMC_DEBUG
		dev_dbg(mmc_dev(host->mmc), "MMC IRQ %04x (CMD %d): ",
743
			status, cmd);
C
Carlos Aguiar 已提交
744 745 746 747 748 749 750 751 752 753 754
		mmc_omap_report_irq(status);
		printk("\n");
#endif
		if (host->total_bytes_left) {
			if ((status & OMAP_MMC_STAT_A_FULL) ||
			    (status & OMAP_MMC_STAT_END_OF_DATA))
				mmc_omap_xfer_data(host, 0);
			if (status & OMAP_MMC_STAT_A_EMPTY)
				mmc_omap_xfer_data(host, 1);
		}

755
		if (status & OMAP_MMC_STAT_END_OF_DATA)
C
Carlos Aguiar 已提交
756 757 758
			end_transfer = 1;

		if (status & OMAP_MMC_STAT_DATA_TOUT) {
759 760
			dev_dbg(mmc_dev(host->mmc), "data timeout (CMD%d)\n",
				cmd);
C
Carlos Aguiar 已提交
761
			if (host->data) {
P
Pierre Ossman 已提交
762
				host->data->error = -ETIMEDOUT;
C
Carlos Aguiar 已提交
763 764 765 766 767 768
				transfer_error = 1;
			}
		}

		if (status & OMAP_MMC_STAT_DATA_CRC) {
			if (host->data) {
P
Pierre Ossman 已提交
769
				host->data->error = -EILSEQ;
C
Carlos Aguiar 已提交
770 771 772 773 774 775 776 777 778 779 780 781
				dev_dbg(mmc_dev(host->mmc),
					 "data CRC error, bytes left %d\n",
					host->total_bytes_left);
				transfer_error = 1;
			} else {
				dev_dbg(mmc_dev(host->mmc), "data CRC error\n");
			}
		}

		if (status & OMAP_MMC_STAT_CMD_TOUT) {
			/* Timeouts are routine with some commands */
			if (host->cmd) {
782 783
				struct mmc_omap_slot *slot =
					host->current_slot;
784 785
				if (slot == NULL ||
				    !mmc_omap_cover_is_open(slot))
786
					dev_err(mmc_dev(host->mmc),
787 788
						"command timeout (CMD%d)\n",
						cmd);
P
Pierre Ossman 已提交
789
				host->cmd->error = -ETIMEDOUT;
C
Carlos Aguiar 已提交
790
				end_command = 1;
791
				cmd_error = 1;
C
Carlos Aguiar 已提交
792 793 794 795 796 797 798
			}
		}

		if (status & OMAP_MMC_STAT_CMD_CRC) {
			if (host->cmd) {
				dev_err(mmc_dev(host->mmc),
					"command CRC error (CMD%d, arg 0x%08x)\n",
799
					cmd, host->cmd->arg);
P
Pierre Ossman 已提交
800
				host->cmd->error = -EILSEQ;
C
Carlos Aguiar 已提交
801
				end_command = 1;
802
				cmd_error = 1;
C
Carlos Aguiar 已提交
803 804 805 806 807 808
			} else
				dev_err(mmc_dev(host->mmc),
					"command CRC error without cmd?\n");
		}

		if (status & OMAP_MMC_STAT_CARD_ERR) {
809 810
			dev_dbg(mmc_dev(host->mmc),
				"ignoring card status error (CMD%d)\n",
811
				cmd);
812
			end_command = 1;
C
Carlos Aguiar 已提交
813 814 815 816
		}

		/*
		 * NOTE: On 1610 the END_OF_CMD may come too early when
817
		 * starting a write
C
Carlos Aguiar 已提交
818 819 820 821 822 823 824
		 */
		if ((status & OMAP_MMC_STAT_END_OF_CMD) &&
		    (!(status & OMAP_MMC_STAT_A_EMPTY))) {
			end_command = 1;
		}
	}

825 826 827 828
	if (cmd_error && host->data) {
		del_timer(&host->cmd_abort_timer);
		host->abort = 1;
		OMAP_MMC_WRITE(host, IE, 0);
829
		disable_irq_nosync(host->irq);
830
		queue_work(host->mmc_omap_wq, &host->cmd_abort_work);
831 832 833
		return IRQ_HANDLED;
	}

834
	if (end_command && host->cmd)
C
Carlos Aguiar 已提交
835
		mmc_omap_cmd_done(host, host->cmd);
836 837 838 839 840
	if (host->data != NULL) {
		if (transfer_error)
			mmc_omap_xfer_done(host, host->data);
		else if (end_transfer)
			mmc_omap_end_of_data(host, host->data);
C
Carlos Aguiar 已提交
841 842 843 844 845
	}

	return IRQ_HANDLED;
}

846
void omap_mmc_notify_cover_event(struct device *dev, int num, int is_closed)
847
{
848
	int cover_open;
849
	struct mmc_omap_host *host = dev_get_drvdata(dev);
850
	struct mmc_omap_slot *slot = host->slots[num];
851

852
	BUG_ON(num >= host->nr_slots);
853 854

	/* Other subsystems can call in here before we're initialised. */
855
	if (host->nr_slots == 0 || !host->slots[num])
856 857
		return;

858 859 860 861 862 863 864
	cover_open = mmc_omap_cover_is_open(slot);
	if (cover_open != slot->cover_open) {
		slot->cover_open = cover_open;
		sysfs_notify(&slot->mmc->class_dev.kobj, NULL, "cover_switch");
	}

	tasklet_hi_schedule(&slot->cover_tasklet);
865 866
}

867
static void mmc_omap_cover_timer(unsigned long arg)
868 869
{
	struct mmc_omap_slot *slot = (struct mmc_omap_slot *) arg;
870
	tasklet_schedule(&slot->cover_tasklet);
871 872
}

873
static void mmc_omap_cover_handler(unsigned long param)
874
{
875 876
	struct mmc_omap_slot *slot = (struct mmc_omap_slot *)param;
	int cover_open = mmc_omap_cover_is_open(slot);
877

878 879 880 881 882 883 884 885 886 887 888 889 890
	mmc_detect_change(slot->mmc, 0);
	if (!cover_open)
		return;

	/*
	 * If no card is inserted, we postpone polling until
	 * the cover has been closed.
	 */
	if (slot->mmc->card == NULL || !mmc_card_present(slot->mmc->card))
		return;

	mod_timer(&slot->cover_timer,
		  jiffies + msecs_to_jiffies(OMAP_MMC_COVER_POLL_DELAY));
891 892
}

R
Russell King 已提交
893 894 895 896 897 898 899 900 901 902 903
static void mmc_omap_dma_callback(void *priv)
{
	struct mmc_omap_host *host = priv;
	struct mmc_data *data = host->data;

	/* If we got to the end of DMA, assume everything went well */
	data->bytes_xfered += data->blocks * data->blksz;

	mmc_omap_dma_done(host, data);
}

C
Carlos Aguiar 已提交
904 905 906 907
static inline void set_cmd_timeout(struct mmc_omap_host *host, struct mmc_request *req)
{
	u16 reg;

908
	reg = OMAP_MMC_READ(host, SDIO);
C
Carlos Aguiar 已提交
909
	reg &= ~(1 << 5);
910
	OMAP_MMC_WRITE(host, SDIO, reg);
C
Carlos Aguiar 已提交
911
	/* Set maximum timeout */
912
	OMAP_MMC_WRITE(host, CTO, 0xff);
C
Carlos Aguiar 已提交
913 914 915 916
}

static inline void set_data_timeout(struct mmc_omap_host *host, struct mmc_request *req)
{
917
	unsigned int timeout, cycle_ns;
C
Carlos Aguiar 已提交
918 919
	u16 reg;

920 921 922
	cycle_ns = 1000000000 / host->current_slot->fclk_freq;
	timeout = req->data->timeout_ns / cycle_ns;
	timeout += req->data->timeout_clks;
C
Carlos Aguiar 已提交
923 924

	/* Check if we need to use timeout multiplier register */
925
	reg = OMAP_MMC_READ(host, SDIO);
C
Carlos Aguiar 已提交
926 927 928 929 930
	if (timeout > 0xffff) {
		reg |= (1 << 5);
		timeout /= 1024;
	} else
		reg &= ~(1 << 5);
931 932
	OMAP_MMC_WRITE(host, SDIO, reg);
	OMAP_MMC_WRITE(host, DTO, timeout);
C
Carlos Aguiar 已提交
933 934 935 936 937 938 939 940 941 942 943
}

static void
mmc_omap_prepare_data(struct mmc_omap_host *host, struct mmc_request *req)
{
	struct mmc_data *data = req->data;
	int i, use_dma, block_size;
	unsigned sg_len;

	host->data = data;
	if (data == NULL) {
944 945 946
		OMAP_MMC_WRITE(host, BLEN, 0);
		OMAP_MMC_WRITE(host, NBLK, 0);
		OMAP_MMC_WRITE(host, BUF, 0);
C
Carlos Aguiar 已提交
947 948 949 950 951
		host->dma_in_use = 0;
		set_cmd_timeout(host, req);
		return;
	}

952
	block_size = data->blksz;
C
Carlos Aguiar 已提交
953

954 955
	OMAP_MMC_WRITE(host, NBLK, data->blocks - 1);
	OMAP_MMC_WRITE(host, BLEN, block_size - 1);
C
Carlos Aguiar 已提交
956 957 958 959 960 961 962 963 964 965 966 967 968 969 970 971 972 973 974
	set_data_timeout(host, req);

	/* cope with calling layer confusion; it issues "single
	 * block" writes using multi-block scatterlists.
	 */
	sg_len = (data->blocks == 1) ? 1 : data->sg_len;

	/* Only do DMA for entire blocks */
	use_dma = host->use_dma;
	if (use_dma) {
		for (i = 0; i < sg_len; i++) {
			if ((data->sg[i].length % block_size) != 0) {
				use_dma = 0;
				break;
			}
		}
	}

	host->sg_idx = 0;
R
Russell King 已提交
975 976 977 978 979 980 981 982 983 984 985 986 987 988 989 990 991 992 993 994 995 996 997 998 999 1000 1001 1002 1003 1004 1005 1006 1007 1008 1009 1010 1011 1012 1013 1014 1015 1016 1017 1018 1019 1020 1021 1022 1023 1024 1025 1026 1027 1028 1029 1030 1031 1032 1033 1034 1035 1036 1037 1038 1039 1040 1041 1042 1043 1044 1045 1046 1047
	if (use_dma) {
		enum dma_data_direction dma_data_dir;
		struct dma_async_tx_descriptor *tx;
		struct dma_chan *c;
		u32 burst, *bp;
		u16 buf;

		/*
		 * FIFO is 16x2 bytes on 15xx, and 32x2 bytes on 16xx
		 * and 24xx. Use 16 or 32 word frames when the
		 * blocksize is at least that large. Blocksize is
		 * usually 512 bytes; but not for some SD reads.
		 */
		burst = cpu_is_omap15xx() ? 32 : 64;
		if (burst > data->blksz)
			burst = data->blksz;

		burst >>= 1;

		if (data->flags & MMC_DATA_WRITE) {
			c = host->dma_tx;
			bp = &host->dma_tx_burst;
			buf = 0x0f80 | (burst - 1) << 0;
			dma_data_dir = DMA_TO_DEVICE;
		} else {
			c = host->dma_rx;
			bp = &host->dma_rx_burst;
			buf = 0x800f | (burst - 1) << 8;
			dma_data_dir = DMA_FROM_DEVICE;
		}

		if (!c)
			goto use_pio;

		/* Only reconfigure if we have a different burst size */
		if (*bp != burst) {
			struct dma_slave_config cfg;

			cfg.src_addr = host->phys_base + OMAP_MMC_REG(host, DATA);
			cfg.dst_addr = host->phys_base + OMAP_MMC_REG(host, DATA);
			cfg.src_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
			cfg.dst_addr_width = DMA_SLAVE_BUSWIDTH_2_BYTES;
			cfg.src_maxburst = burst;
			cfg.dst_maxburst = burst;

			if (dmaengine_slave_config(c, &cfg))
				goto use_pio;

			*bp = burst;
		}

		host->sg_len = dma_map_sg(c->device->dev, data->sg, sg_len,
					  dma_data_dir);
		if (host->sg_len == 0)
			goto use_pio;

		tx = dmaengine_prep_slave_sg(c, data->sg, host->sg_len,
			data->flags & MMC_DATA_WRITE ? DMA_MEM_TO_DEV : DMA_DEV_TO_MEM,
			DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
		if (!tx)
			goto use_pio;

		OMAP_MMC_WRITE(host, BUF, buf);

		tx->callback = mmc_omap_dma_callback;
		tx->callback_param = host;
		dmaengine_submit(tx);
		host->brs_received = 0;
		host->dma_done = 0;
		host->dma_in_use = 1;
		return;
	}
 use_pio:
C
Carlos Aguiar 已提交
1048 1049

	/* Revert to PIO? */
1050 1051 1052 1053 1054
	OMAP_MMC_WRITE(host, BUF, 0x1f1f);
	host->total_bytes_left = data->blocks * block_size;
	host->sg_len = sg_len;
	mmc_omap_sg_to_buf(host);
	host->dma_in_use = 0;
C
Carlos Aguiar 已提交
1055 1056
}

1057 1058
static void mmc_omap_start_request(struct mmc_omap_host *host,
				   struct mmc_request *req)
C
Carlos Aguiar 已提交
1059
{
1060
	BUG_ON(host->mrq != NULL);
C
Carlos Aguiar 已提交
1061 1062 1063 1064 1065 1066

	host->mrq = req;

	/* only touch fifo AFTER the controller readies it */
	mmc_omap_prepare_data(host, req);
	mmc_omap_start_command(host, req->cmd);
R
Russell King 已提交
1067 1068 1069 1070
	if (host->dma_in_use) {
		struct dma_chan *c = host->data->flags & MMC_DATA_WRITE ?
				host->dma_tx : host->dma_rx;

1071
		dma_async_issue_pending(c);
R
Russell King 已提交
1072
	}
1073 1074 1075 1076 1077 1078 1079 1080 1081 1082 1083 1084 1085 1086 1087 1088 1089 1090 1091
}

static void mmc_omap_request(struct mmc_host *mmc, struct mmc_request *req)
{
	struct mmc_omap_slot *slot = mmc_priv(mmc);
	struct mmc_omap_host *host = slot->host;
	unsigned long flags;

	spin_lock_irqsave(&host->slot_lock, flags);
	if (host->mmc != NULL) {
		BUG_ON(slot->mrq != NULL);
		slot->mrq = req;
		spin_unlock_irqrestore(&host->slot_lock, flags);
		return;
	} else
		host->mmc = mmc;
	spin_unlock_irqrestore(&host->slot_lock, flags);
	mmc_omap_select_slot(slot, 1);
	mmc_omap_start_request(host, req);
C
Carlos Aguiar 已提交
1092 1093
}

1094 1095
static void mmc_omap_set_power(struct mmc_omap_slot *slot, int power_on,
				int vdd)
C
Carlos Aguiar 已提交
1096
{
1097
	struct mmc_omap_host *host;
C
Carlos Aguiar 已提交
1098

1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114
	host = slot->host;

	if (slot->pdata->set_power != NULL)
		slot->pdata->set_power(mmc_dev(slot->mmc), slot->id, power_on,
					vdd);

	if (cpu_is_omap24xx()) {
		u16 w;

		if (power_on) {
			w = OMAP_MMC_READ(host, CON);
			OMAP_MMC_WRITE(host, CON, w | (1 << 11));
		} else {
			w = OMAP_MMC_READ(host, CON);
			OMAP_MMC_WRITE(host, CON, w & ~(1 << 11));
		}
C
Carlos Aguiar 已提交
1115 1116 1117
	}
}

1118
static int mmc_omap_calc_divisor(struct mmc_host *mmc, struct mmc_ios *ios)
C
Carlos Aguiar 已提交
1119
{
1120 1121
	struct mmc_omap_slot *slot = mmc_priv(mmc);
	struct mmc_omap_host *host = slot->host;
1122
	int func_clk_rate = clk_get_rate(host->fclk);
C
Carlos Aguiar 已提交
1123 1124 1125
	int dsor;

	if (ios->clock == 0)
1126
		return 0;
C
Carlos Aguiar 已提交
1127

1128 1129 1130
	dsor = func_clk_rate / ios->clock;
	if (dsor < 1)
		dsor = 1;
C
Carlos Aguiar 已提交
1131

1132
	if (func_clk_rate / dsor > ios->clock)
C
Carlos Aguiar 已提交
1133 1134
		dsor++;

1135 1136 1137
	if (dsor > 250)
		dsor = 250;

1138 1139
	slot->fclk_freq = func_clk_rate / dsor;

1140 1141 1142 1143 1144 1145 1146 1147
	if (ios->bus_width == MMC_BUS_WIDTH_4)
		dsor |= 1 << 15;

	return dsor;
}

static void mmc_omap_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
{
1148 1149 1150
	struct mmc_omap_slot *slot = mmc_priv(mmc);
	struct mmc_omap_host *host = slot->host;
	int i, dsor;
J
Jarkko Lavinen 已提交
1151
	int clk_enabled;
1152 1153 1154

	mmc_omap_select_slot(slot, 0);

J
Jarkko Lavinen 已提交
1155 1156
	dsor = mmc_omap_calc_divisor(mmc, ios);

1157 1158
	if (ios->vdd != slot->vdd)
		slot->vdd = ios->vdd;
C
Carlos Aguiar 已提交
1159

J
Jarkko Lavinen 已提交
1160
	clk_enabled = 0;
C
Carlos Aguiar 已提交
1161 1162
	switch (ios->power_mode) {
	case MMC_POWER_OFF:
1163
		mmc_omap_set_power(slot, 0, ios->vdd);
C
Carlos Aguiar 已提交
1164 1165
		break;
	case MMC_POWER_UP:
1166
		/* Cannot touch dsor yet, just power up MMC */
1167 1168
		mmc_omap_set_power(slot, 1, ios->vdd);
		goto exit;
1169
	case MMC_POWER_ON:
J
Jarkko Lavinen 已提交
1170 1171
		mmc_omap_fclk_enable(host, 1);
		clk_enabled = 1;
1172
		dsor |= 1 << 11;
C
Carlos Aguiar 已提交
1173 1174 1175
		break;
	}

1176 1177 1178 1179 1180 1181
	if (slot->bus_mode != ios->bus_mode) {
		if (slot->pdata->set_bus_mode != NULL)
			slot->pdata->set_bus_mode(mmc_dev(mmc), slot->id,
						  ios->bus_mode);
		slot->bus_mode = ios->bus_mode;
	}
C
Carlos Aguiar 已提交
1182 1183 1184 1185 1186 1187

	/* On insanely high arm_per frequencies something sometimes
	 * goes somehow out of sync, and the POW bit is not being set,
	 * which results in the while loop below getting stuck.
	 * Writing to the CON register twice seems to do the trick. */
	for (i = 0; i < 2; i++)
1188
		OMAP_MMC_WRITE(host, CON, dsor);
1189
	slot->saved_con = dsor;
1190
	if (ios->power_mode == MMC_POWER_ON) {
1191 1192 1193
		/* worst case at 400kHz, 80 cycles makes 200 microsecs */
		int usecs = 250;

C
Carlos Aguiar 已提交
1194
		/* Send clock cycles, poll completion */
1195 1196
		OMAP_MMC_WRITE(host, IE, 0);
		OMAP_MMC_WRITE(host, STAT, 0xffff);
1197
		OMAP_MMC_WRITE(host, CMD, 1 << 7);
1198 1199 1200 1201
		while (usecs > 0 && (OMAP_MMC_READ(host, STAT) & 1) == 0) {
			udelay(1);
			usecs--;
		}
1202
		OMAP_MMC_WRITE(host, STAT, 1);
C
Carlos Aguiar 已提交
1203
	}
1204 1205

exit:
J
Jarkko Lavinen 已提交
1206
	mmc_omap_release_slot(slot, clk_enabled);
C
Carlos Aguiar 已提交
1207 1208
}

1209
static const struct mmc_host_ops mmc_omap_ops = {
C
Carlos Aguiar 已提交
1210 1211 1212 1213
	.request	= mmc_omap_request,
	.set_ios	= mmc_omap_set_ios,
};

1214
static int __devinit mmc_omap_new_slot(struct mmc_omap_host *host, int id)
C
Carlos Aguiar 已提交
1215
{
1216
	struct mmc_omap_slot *slot = NULL;
C
Carlos Aguiar 已提交
1217
	struct mmc_host *mmc;
1218 1219 1220 1221 1222 1223 1224 1225 1226 1227 1228 1229 1230 1231
	int r;

	mmc = mmc_alloc_host(sizeof(struct mmc_omap_slot), host->dev);
	if (mmc == NULL)
		return -ENOMEM;

	slot = mmc_priv(mmc);
	slot->host = host;
	slot->mmc = mmc;
	slot->id = id;
	slot->pdata = &host->pdata->slots[id];

	host->slots[id] = slot;

1232
	mmc->caps = 0;
1233
	if (host->pdata->slots[id].wires >= 4)
1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250
		mmc->caps |= MMC_CAP_4_BIT_DATA;

	mmc->ops = &mmc_omap_ops;
	mmc->f_min = 400000;

	if (cpu_class_is_omap2())
		mmc->f_max = 48000000;
	else
		mmc->f_max = 24000000;
	if (host->pdata->max_freq)
		mmc->f_max = min(host->pdata->max_freq, mmc->f_max);
	mmc->ocr_avail = slot->pdata->ocr_mask;

	/* Use scatterlist DMA to reduce per-transfer costs.
	 * NOTE max_seg_size assumption that small blocks aren't
	 * normally used (except e.g. for reading SD registers).
	 */
1251
	mmc->max_segs = 32;
1252 1253 1254 1255 1256 1257 1258 1259 1260 1261 1262 1263 1264 1265 1266 1267
	mmc->max_blk_size = 2048;	/* BLEN is 11 bits (+1) */
	mmc->max_blk_count = 2048;	/* NBLK is 11 bits (+1) */
	mmc->max_req_size = mmc->max_blk_size * mmc->max_blk_count;
	mmc->max_seg_size = mmc->max_req_size;

	r = mmc_add_host(mmc);
	if (r < 0)
		goto err_remove_host;

	if (slot->pdata->name != NULL) {
		r = device_create_file(&mmc->class_dev,
					&dev_attr_slot_name);
		if (r < 0)
			goto err_remove_host;
	}

1268 1269 1270 1271 1272 1273
	if (slot->pdata->get_cover_state != NULL) {
		r = device_create_file(&mmc->class_dev,
					&dev_attr_cover_switch);
		if (r < 0)
			goto err_remove_slot_name;

1274 1275 1276 1277 1278
		setup_timer(&slot->cover_timer, mmc_omap_cover_timer,
			    (unsigned long)slot);
		tasklet_init(&slot->cover_tasklet, mmc_omap_cover_handler,
			     (unsigned long)slot);
		tasklet_schedule(&slot->cover_tasklet);
1279 1280
	}

1281 1282
	return 0;

1283 1284 1285
err_remove_slot_name:
	if (slot->pdata->name != NULL)
		device_remove_file(&mmc->class_dev, &dev_attr_slot_name);
1286 1287 1288 1289 1290 1291 1292 1293 1294 1295 1296 1297
err_remove_host:
	mmc_remove_host(mmc);
	mmc_free_host(mmc);
	return r;
}

static void mmc_omap_remove_slot(struct mmc_omap_slot *slot)
{
	struct mmc_host *mmc = slot->mmc;

	if (slot->pdata->name != NULL)
		device_remove_file(&mmc->class_dev, &dev_attr_slot_name);
1298 1299 1300
	if (slot->pdata->get_cover_state != NULL)
		device_remove_file(&mmc->class_dev, &dev_attr_cover_switch);

1301 1302
	tasklet_kill(&slot->cover_tasklet);
	del_timer_sync(&slot->cover_timer);
1303
	flush_workqueue(slot->host->mmc_omap_wq);
1304 1305 1306 1307 1308

	mmc_remove_host(mmc);
	mmc_free_host(mmc);
}

1309
static int __devinit mmc_omap_probe(struct platform_device *pdev)
1310 1311
{
	struct omap_mmc_platform_data *pdata = pdev->dev.platform_data;
C
Carlos Aguiar 已提交
1312
	struct mmc_omap_host *host = NULL;
1313
	struct resource *res;
R
Russell King 已提交
1314 1315
	dma_cap_mask_t mask;
	unsigned sig;
1316
	int i, ret = 0;
1317
	int irq;
1318

1319
	if (pdata == NULL) {
1320 1321 1322
		dev_err(&pdev->dev, "platform data missing\n");
		return -ENXIO;
	}
1323 1324 1325 1326
	if (pdata->nr_slots == 0) {
		dev_err(&pdev->dev, "no slots\n");
		return -ENXIO;
	}
1327 1328

	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
1329
	irq = platform_get_irq(pdev, 0);
1330
	if (res == NULL || irq < 0)
1331
		return -ENXIO;
C
Carlos Aguiar 已提交
1332

1333
	res = request_mem_region(res->start, resource_size(res),
1334
				 pdev->name);
1335
	if (res == NULL)
C
Carlos Aguiar 已提交
1336 1337
		return -EBUSY;

1338 1339
	host = kzalloc(sizeof(struct mmc_omap_host), GFP_KERNEL);
	if (host == NULL) {
C
Carlos Aguiar 已提交
1340
		ret = -ENOMEM;
1341
		goto err_free_mem_region;
C
Carlos Aguiar 已提交
1342 1343
	}

1344 1345 1346
	INIT_WORK(&host->slot_release_work, mmc_omap_slot_release_work);
	INIT_WORK(&host->send_stop_work, mmc_omap_send_stop_work);

1347 1348 1349
	INIT_WORK(&host->cmd_abort_work, mmc_omap_abort_command);
	setup_timer(&host->cmd_abort_timer, mmc_omap_cmd_timer,
		    (unsigned long) host);
J
Jarkko Lavinen 已提交
1350

J
Jarkko Lavinen 已提交
1351 1352 1353
	spin_lock_init(&host->clk_lock);
	setup_timer(&host->clk_timer, mmc_omap_clk_timer, (unsigned long) host);

C
Carlos Aguiar 已提交
1354
	spin_lock_init(&host->dma_lock);
1355 1356 1357 1358 1359 1360 1361
	spin_lock_init(&host->slot_lock);
	init_waitqueue_head(&host->slot_wq);

	host->pdata = pdata;
	host->dev = &pdev->dev;
	platform_set_drvdata(pdev, host);

C
Carlos Aguiar 已提交
1362
	host->id = pdev->id;
1363
	host->mem_res = res;
1364
	host->irq = irq;
1365 1366 1367
	host->use_dma = 1;
	host->irq = irq;
	host->phys_base = host->mem_res->start;
1368
	host->virt_base = ioremap(res->start, resource_size(res));
1369 1370
	if (!host->virt_base)
		goto err_ioremap;
1371

1372
	host->iclk = clk_get(&pdev->dev, "ick");
1373 1374
	if (IS_ERR(host->iclk)) {
		ret = PTR_ERR(host->iclk);
1375
		goto err_free_mmc_host;
1376
	}
1377
	clk_enable(host->iclk);
C
Carlos Aguiar 已提交
1378

1379
	host->fclk = clk_get(&pdev->dev, "fck");
C
Carlos Aguiar 已提交
1380 1381
	if (IS_ERR(host->fclk)) {
		ret = PTR_ERR(host->fclk);
1382
		goto err_free_iclk;
C
Carlos Aguiar 已提交
1383 1384
	}

R
Russell King 已提交
1385 1386 1387 1388 1389 1390 1391 1392 1393 1394 1395 1396 1397 1398 1399 1400 1401 1402 1403 1404 1405 1406 1407 1408 1409 1410 1411 1412 1413 1414 1415 1416 1417 1418 1419 1420 1421 1422 1423
	dma_cap_zero(mask);
	dma_cap_set(DMA_SLAVE, mask);

	host->dma_tx_burst = -1;
	host->dma_rx_burst = -1;

	if (cpu_is_omap24xx())
		sig = host->id == 0 ? OMAP24XX_DMA_MMC1_TX : OMAP24XX_DMA_MMC2_TX;
	else
		sig = host->id == 0 ? OMAP_DMA_MMC_TX : OMAP_DMA_MMC2_TX;
	host->dma_tx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
#if 0
	if (!host->dma_tx) {
		dev_err(host->dev, "unable to obtain TX DMA engine channel %u\n",
			sig);
		goto err_dma;
	}
#else
	if (!host->dma_tx)
		dev_warn(host->dev, "unable to obtain TX DMA engine channel %u\n",
			sig);
#endif
	if (cpu_is_omap24xx())
		sig = host->id == 0 ? OMAP24XX_DMA_MMC1_RX : OMAP24XX_DMA_MMC2_RX;
	else
		sig = host->id == 0 ? OMAP_DMA_MMC_RX : OMAP_DMA_MMC2_RX;
	host->dma_rx = dma_request_channel(mask, omap_dma_filter_fn, &sig);
#if 0
	if (!host->dma_rx) {
		dev_err(host->dev, "unable to obtain RX DMA engine channel %u\n",
			sig);
		goto err_dma;
	}
#else
	if (!host->dma_rx)
		dev_warn(host->dev, "unable to obtain RX DMA engine channel %u\n",
			sig);
#endif

1424 1425
	ret = request_irq(host->irq, mmc_omap_irq, 0, DRIVER_NAME, host);
	if (ret)
R
Russell King 已提交
1426
		goto err_free_dma;
1427

1428 1429 1430 1431 1432
	if (pdata->init != NULL) {
		ret = pdata->init(&pdev->dev);
		if (ret < 0)
			goto err_free_irq;
	}
C
Carlos Aguiar 已提交
1433

1434
	host->nr_slots = pdata->nr_slots;
1435
	host->reg_shift = (cpu_is_omap7xx() ? 1 : 2);
1436 1437 1438 1439 1440

	host->mmc_omap_wq = alloc_workqueue("mmc_omap", 0, 0);
	if (!host->mmc_omap_wq)
		goto err_plat_cleanup;

1441 1442 1443 1444 1445
	for (i = 0; i < pdata->nr_slots; i++) {
		ret = mmc_omap_new_slot(host, i);
		if (ret < 0) {
			while (--i >= 0)
				mmc_omap_remove_slot(host->slots[i]);
C
Carlos Aguiar 已提交
1446

1447
			goto err_destroy_wq;
C
Carlos Aguiar 已提交
1448 1449 1450 1451 1452
		}
	}

	return 0;

1453 1454
err_destroy_wq:
	destroy_workqueue(host->mmc_omap_wq);
1455 1456 1457 1458 1459
err_plat_cleanup:
	if (pdata->cleanup)
		pdata->cleanup(&pdev->dev);
err_free_irq:
	free_irq(host->irq, host);
R
Russell King 已提交
1460 1461 1462 1463 1464
err_free_dma:
	if (host->dma_tx)
		dma_release_channel(host->dma_tx);
	if (host->dma_rx)
		dma_release_channel(host->dma_rx);
1465 1466
	clk_put(host->fclk);
err_free_iclk:
1467 1468
	clk_disable(host->iclk);
	clk_put(host->iclk);
1469
err_free_mmc_host:
1470 1471
	iounmap(host->virt_base);
err_ioremap:
1472
	kfree(host);
1473
err_free_mem_region:
1474
	release_mem_region(res->start, resource_size(res));
C
Carlos Aguiar 已提交
1475 1476 1477
	return ret;
}

1478
static int __devexit mmc_omap_remove(struct platform_device *pdev)
C
Carlos Aguiar 已提交
1479 1480
{
	struct mmc_omap_host *host = platform_get_drvdata(pdev);
1481
	int i;
C
Carlos Aguiar 已提交
1482 1483 1484

	platform_set_drvdata(pdev, NULL);

1485 1486
	BUG_ON(host == NULL);

1487 1488 1489 1490 1491
	for (i = 0; i < host->nr_slots; i++)
		mmc_omap_remove_slot(host->slots[i]);

	if (host->pdata->cleanup)
		host->pdata->cleanup(&pdev->dev);
1492

1493
	mmc_omap_fclk_enable(host, 0);
L
Ladislav Michl 已提交
1494
	free_irq(host->irq, host);
1495 1496 1497
	clk_put(host->fclk);
	clk_disable(host->iclk);
	clk_put(host->iclk);
C
Carlos Aguiar 已提交
1498

R
Russell King 已提交
1499 1500 1501 1502 1503
	if (host->dma_tx)
		dma_release_channel(host->dma_tx);
	if (host->dma_rx)
		dma_release_channel(host->dma_rx);

1504
	iounmap(host->virt_base);
C
Carlos Aguiar 已提交
1505
	release_mem_region(pdev->resource[0].start,
1506
			   pdev->resource[0].end - pdev->resource[0].start + 1);
1507
	destroy_workqueue(host->mmc_omap_wq);
1508

1509
	kfree(host);
C
Carlos Aguiar 已提交
1510 1511 1512 1513 1514 1515 1516

	return 0;
}

#ifdef CONFIG_PM
static int mmc_omap_suspend(struct platform_device *pdev, pm_message_t mesg)
{
1517
	int i, ret = 0;
C
Carlos Aguiar 已提交
1518 1519
	struct mmc_omap_host *host = platform_get_drvdata(pdev);

1520
	if (host == NULL || host->suspended)
C
Carlos Aguiar 已提交
1521 1522
		return 0;

1523 1524 1525 1526
	for (i = 0; i < host->nr_slots; i++) {
		struct mmc_omap_slot *slot;

		slot = host->slots[i];
1527
		ret = mmc_suspend_host(slot->mmc);
1528 1529 1530 1531 1532 1533 1534
		if (ret < 0) {
			while (--i >= 0) {
				slot = host->slots[i];
				mmc_resume_host(slot->mmc);
			}
			return ret;
		}
C
Carlos Aguiar 已提交
1535
	}
1536 1537
	host->suspended = 1;
	return 0;
C
Carlos Aguiar 已提交
1538 1539 1540 1541
}

static int mmc_omap_resume(struct platform_device *pdev)
{
1542
	int i, ret = 0;
C
Carlos Aguiar 已提交
1543 1544
	struct mmc_omap_host *host = platform_get_drvdata(pdev);

1545
	if (host == NULL || !host->suspended)
C
Carlos Aguiar 已提交
1546 1547
		return 0;

1548 1549 1550 1551 1552 1553
	for (i = 0; i < host->nr_slots; i++) {
		struct mmc_omap_slot *slot;
		slot = host->slots[i];
		ret = mmc_resume_host(slot->mmc);
		if (ret < 0)
			return ret;
C
Carlos Aguiar 已提交
1554

1555 1556 1557
		host->suspended = 0;
	}
	return 0;
C
Carlos Aguiar 已提交
1558 1559 1560 1561 1562 1563 1564
}
#else
#define mmc_omap_suspend	NULL
#define mmc_omap_resume		NULL
#endif

static struct platform_driver mmc_omap_driver = {
1565 1566
	.probe		= mmc_omap_probe,
	.remove		= __devexit_p(mmc_omap_remove),
C
Carlos Aguiar 已提交
1567 1568 1569 1570
	.suspend	= mmc_omap_suspend,
	.resume		= mmc_omap_resume,
	.driver		= {
		.name	= DRIVER_NAME,
1571
		.owner	= THIS_MODULE,
C
Carlos Aguiar 已提交
1572 1573 1574
	},
};

1575
module_platform_driver(mmc_omap_driver);
C
Carlos Aguiar 已提交
1576 1577
MODULE_DESCRIPTION("OMAP Multimedia Card driver");
MODULE_LICENSE("GPL");
1578
MODULE_ALIAS("platform:" DRIVER_NAME);
A
Al Viro 已提交
1579
MODULE_AUTHOR("Juha Yrjölä");