1 From e37b54bbb7d7df4dc2fff9846daabbb6c552d47d Mon Sep 17 00:00:00 2001
2 From: mokopatches <mokopatches@openmoko.org>
3 Date: Fri, 4 Apr 2008 11:35:05 +0100
4 Subject: [PATCH] glamo-mmc.patch
7 drivers/mfd/glamo/Kconfig | 9 +
8 drivers/mfd/glamo/Makefile | 1 +
9 drivers/mfd/glamo/glamo-core.c | 17 +-
10 drivers/mfd/glamo/glamo-mci.c | 837 ++++++++++++++++++++++++++++++++++++++++
11 drivers/mfd/glamo/glamo-mci.h | 76 ++++
12 drivers/mfd/glamo/glamo-regs.h | 169 ++++++++-
13 6 files changed, 1099 insertions(+), 10 deletions(-)
14 create mode 100644 drivers/mfd/glamo/glamo-mci.c
15 create mode 100644 drivers/mfd/glamo/glamo-mci.h
17 diff --git a/drivers/mfd/glamo/Kconfig b/drivers/mfd/glamo/Kconfig
18 index b99f2b2..ec2ae3d 100644
19 --- a/drivers/mfd/glamo/Kconfig
20 +++ b/drivers/mfd/glamo/Kconfig
21 @@ -33,3 +33,12 @@ config MFD_GLAMO_SPI_FB
22 control channel. This SPI interface is frequently used to
23 interconnect the LCM control interface.
26 + tristate "Glamo S3C SD/MMC Card Interface support"
27 + depends on MFD_GLAMO && MMC
29 + This selects a driver for the MCI interface found in
30 + the S-Media GLAMO chip, as used in OpenMoko
34 \ No newline at end of file
35 diff --git a/drivers/mfd/glamo/Makefile b/drivers/mfd/glamo/Makefile
36 index fb53982..dc64d50 100644
37 --- a/drivers/mfd/glamo/Makefile
38 +++ b/drivers/mfd/glamo/Makefile
39 @@ -8,4 +8,5 @@ obj-$(CONFIG_MFD_GLAMO_SPI_GPIO) += glamo-spi-gpio.o
41 obj-$(CONFIG_MFD_GLAMO_FB) += glamo-fb.o
42 obj-$(CONFIG_MFD_GLAMO_SPI_FB) += glamo-lcm-spi.o
43 +obj-$(CONFIG_MFD_GLAMO_MCI) += glamo-mci.o
45 diff --git a/drivers/mfd/glamo/glamo-core.c b/drivers/mfd/glamo/glamo-core.c
46 index acf545f..8497de2 100644
47 --- a/drivers/mfd/glamo/glamo-core.c
48 +++ b/drivers/mfd/glamo/glamo-core.c
49 @@ -440,7 +440,22 @@ int glamo_engine_disable(struct glamo_core *glamo, enum glamo_engine engine)
51 spin_lock(&glamo->lock);
53 - /* FIXME: Implementation */
54 + case GLAMO_ENGINE_MMC:
55 + __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_MMC, 0,
56 + GLAMO_CLOCK_MMC_EN_M9CLK |
57 + GLAMO_CLOCK_MMC_EN_TCLK |
58 + GLAMO_CLOCK_MMC_DG_M9CLK |
59 + GLAMO_CLOCK_MMC_DG_TCLK);
60 + __reg_set_bit_mask(glamo, GLAMO_REG_HOSTBUS(2), 0,
61 + GLAMO_HOSTBUS2_MMIO_EN_MMC);
62 + /* disable the TCLK divider clk input */
63 + __reg_set_bit_mask(glamo, GLAMO_REG_CLOCK_GEN5_1, 0,
64 + GLAMO_CLOCK_GEN51_EN_DIV_TCLK);
65 + /* good idea to hold the thing in reset when we power it off? */
66 +/* writew(readw(glamo->base + GLAMO_REG_CLOCK_MMC) |
67 + GLAMO_CLOCK_MMC_RESET, glamo->base + GLAMO_REG_CLOCK_MMC);
73 diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
75 index 0000000..f559e5e
77 +++ b/drivers/mfd/glamo/glamo-mci.c
80 + * linux/drivers/mmc/host/glamo-mmc.c - Glamo MMC driver
82 + * Copyright (C) 2007 OpenMoko, Inc, Andy Green <andy@openmoko.com>
83 + * Based on S3C MMC driver that was:
84 + * Copyright (C) 2004-2006 maintech GmbH, Thomas Kleffel <tk@maintech.de>
86 + * This program is free software; you can redistribute it and/or modify
87 + * it under the terms of the GNU General Public License version 2 as
88 + * published by the Free Software Foundation.
91 +#include <linux/module.h>
92 +#include <linux/dma-mapping.h>
93 +#include <linux/clk.h>
94 +#include <linux/mmc/mmc.h>
95 +#include <linux/mmc/host.h>
96 +#include <linux/platform_device.h>
97 +#include <linux/irq.h>
98 +#include <linux/pcf50633.h>
99 +#include <linux/delay.h>
100 +#include <linux/interrupt.h>
102 +#include <asm/dma.h>
103 +#include <asm/dma-mapping.h>
106 +#include "glamo-mci.h"
107 +#include "glamo-core.h"
108 +#include "glamo-regs.h"
110 +/* from glamo-core.c */
111 +extern struct glamo_mci_pdata glamo_mci_def_pdata;
114 +#define DRIVER_NAME "glamo-mci"
115 +#define RESSIZE(ressource) (((ressource)->end - (ressource)->start) + 1)
117 +static void glamo_mci_send_request(struct mmc_host *mmc);
119 +unsigned char CRC7(u8 * pu8, int cnt)
126 + for (n = 0; n < 8; n++) {
128 + if ((d & 0x80) ^ (crc & 0x80))
133 + return (crc << 1) | 1;
136 +/* these _dly versions account for the dead time rules for reg access */
137 +static u16 readw_dly(u16 __iomem * pu16)
139 + glamo_reg_access_delay();
140 + return readw(pu16);
143 +static void writew_dly(u16 val, u16 __iomem * pu16)
145 + glamo_reg_access_delay();
149 +static int get_data_buffer(struct glamo_mci_host *host,
150 + volatile u32 *words, volatile u16 **pointer)
152 + struct scatterlist *sg;
157 + if (host->pio_active == XFER_NONE)
160 + if ((!host->mrq) || (!host->mrq->data))
163 + if (host->pio_sgptr >= host->mrq->data->sg_len) {
164 + dev_dbg(&host->pdev->dev, "no more buffers (%i/%i)\n",
165 + host->pio_sgptr, host->mrq->data->sg_len);
168 + sg = &host->mrq->data->sg[host->pio_sgptr];
170 + *words = sg->length >> 1; /* we are working with a 16-bit data bus */
171 + *pointer = page_address(sg_page(sg)) + sg->offset;
173 + BUG_ON(((long)(*pointer)) & 1);
177 + /* dev_info(&host->pdev->dev, "new buffer (%i/%i)\n",
178 + host->pio_sgptr, host->mrq->data->sg_len); */
182 +static void do_pio_read(struct glamo_mci_host *host)
185 + u16 __iomem *from_ptr = host->base_data + (RESSIZE(host->mem_data) /
192 + res = get_data_buffer(host, &host->pio_words, &host->pio_ptr);
194 + host->pio_active = XFER_NONE;
195 + host->complete_what = COMPLETION_FINALIZE;
197 + dev_dbg(&host->pdev->dev, "pio_read(): "
198 + "complete (no more data).\n");
202 + dev_dbg(&host->pdev->dev, "pio_read(): host->pio_words: %d\n",
205 + host->pio_count += host->pio_words << 1;
208 + block = (u16 *)host->pio_ptr;
209 + res = host->pio_words << 1;
211 + while (host->pio_words--)
212 + *host->pio_ptr++ = *from_ptr++;
214 + print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,
215 + (void *)block, res, 1);
220 +static int do_pio_write(struct glamo_mci_host *host)
223 + volatile u16 __iomem *to_ptr = host->base_data;
226 + dev_dbg(&host->pdev->dev, "pio_write():\n");
228 + res = get_data_buffer(host, &host->pio_words, &host->pio_ptr);
232 + dev_dbg(&host->pdev->dev, "pio_write():new source: [%i]@[%p]\n",
233 + host->pio_words, host->pio_ptr);
235 + host->pio_count += host->pio_words << 1;
236 + while (host->pio_words--)
237 + writew(*host->pio_ptr++, to_ptr++);
240 + dev_dbg(&host->pdev->dev, "pio_write(): complete\n");
241 + host->pio_active = XFER_NONE;
245 +static void glamo_mci_irq(unsigned int irq, struct irq_desc *desc)
247 + struct glamo_mci_host *host = (struct glamo_mci_host *)
248 + desc->handler_data;
250 + struct mmc_command *cmd;
251 + unsigned long iflags;
257 + cmd = host->mrq->cmd;
261 + spin_lock_irqsave(&host->complete_lock, iflags);
263 + status = readw_dly(host->base + GLAMO_REG_MMC_RB_STAT1);
265 + /* ack this interrupt source */
266 + writew(GLAMO_IRQ_MMC,
267 + glamo_mci_def_pdata.pglamo->base + GLAMO_REG_IRQ_CLEAR);
269 + if (status & (GLAMO_STAT1_MMC_RTOUT |
270 + GLAMO_STAT1_MMC_DTOUT))
271 + cmd->error = -ETIMEDOUT;
272 + if (status & (GLAMO_STAT1_MMC_BWERR |
273 + GLAMO_STAT1_MMC_BRERR))
274 + cmd->error = -EILSEQ;
276 + dev_err(&host->pdev->dev, "Error after cmd: 0x%x\n", status);
280 + if (host->pio_active == XFER_READ)
283 + host->mrq->data->bytes_xfered = host->pio_count;
284 + dev_dbg(&host->pdev->dev, "status = 0x%04x count=%d\n",
285 + status, host->pio_count);
287 + /* issue STOP if we have been given one to use */
288 + if (host->mrq->stop) {
289 + host->cmd_is_stop = 1;
290 + glamo_mci_send_request(host->mmc);
291 + host->cmd_is_stop = 0;
294 + host->complete_what = COMPLETION_NONE;
296 + mmc_request_done(host->mmc, cmd->mrq);
297 + spin_unlock_irqrestore(&host->complete_lock, iflags);
300 +static int glamo_mci_send_command(struct glamo_mci_host *host,
301 + struct mmc_command *cmd)
306 + /* if we can't do it, reject as busy */
307 + if (!readw_dly(host->base + GLAMO_REG_MMC_RB_STAT1) &
308 + GLAMO_STAT1_MMC_IDLE) {
310 + cmd->error = -EBUSY;
311 + mmc_request_done(host->mmc, host->mrq);
315 + /* create an array in wire order for CRC computation */
316 + u8a[0] = 0x40 | (cmd->opcode & 0x3f);
317 + u8a[1] = (u8)(cmd->arg >> 24);
318 + u8a[2] = (u8)(cmd->arg >> 16);
319 + u8a[3] = (u8)(cmd->arg >> 8);
320 + u8a[4] = (u8)cmd->arg;
321 + u8a[5] = CRC7(&u8a[0], 5); /* CRC7 on first 5 bytes of packet */
323 + /* issue the wire-order array including CRC in register order */
324 + writew_dly((u8a[4] << 8) | u8a[5], host->base + GLAMO_REG_MMC_CMD_REG1);
325 + writew_dly((u8a[2] << 8) | u8a[3], host->base + GLAMO_REG_MMC_CMD_REG2);
326 + writew_dly((u8a[0] << 8) | u8a[1], host->base + GLAMO_REG_MMC_CMD_REG3);
328 + /* command index toggle */
329 + fire |= (host->ccnt & 1) << 12;
331 + /* set type of command */
332 + switch (mmc_cmd_type(cmd)) {
334 + fire |= GLAMO_FIRE_MMC_CMDT_BNR;
337 + fire |= GLAMO_FIRE_MMC_CMDT_BR;
340 + fire |= GLAMO_FIRE_MMC_CMDT_AND;
343 + fire |= GLAMO_FIRE_MMC_CMDT_AD;
347 + * if it expects a response, set the type expected
349 + * R1, Length : 48bit, Normal response
350 + * R1b, Length : 48bit, same R1, but added card busy status
351 + * R2, Length : 136bit (really 128 bits with CRC snipped)
352 + * R3, Length : 48bit (OCR register value)
353 + * R4, Length : 48bit, SDIO_OP_CONDITION, Reverse SDIO Card
354 + * R5, Length : 48bit, IO_RW_DIRECTION, Reverse SDIO Card
355 + * R6, Length : 48bit (RCA register)
356 + * R7, Length : 48bit (interface condition, VHS(voltage supplied),
357 + * check pattern, CRC7)
359 + switch (mmc_resp_type(cmd)) {
360 + case MMC_RSP_R6: /* same index as R7 and R1 */
361 + fire |= GLAMO_FIRE_MMC_RSPT_R1;
364 + fire |= GLAMO_FIRE_MMC_RSPT_R1b;
367 + fire |= GLAMO_FIRE_MMC_RSPT_R2;
370 + fire |= GLAMO_FIRE_MMC_RSPT_R3;
372 + /* R4 and R5 supported by chip not defined in linux/mmc/core.h (sdio) */
375 + * From the command index, set up the command class in the host ctrllr
377 + * missing guys present on chip but couldn't figure out how to use yet:
378 + * 0x0 "stream read"
379 + * 0x9 "cancel running command"
381 + switch (cmd->opcode) {
382 + case MMC_READ_SINGLE_BLOCK:
383 + fire |= GLAMO_FIRE_MMC_CC_SBR; /* single block read */
385 + case MMC_SWITCH: /* 64 byte payload */
386 + case 0x33: /* observed issued by MCI */
387 + case MMC_READ_MULTIPLE_BLOCK:
388 + /* we will get an interrupt off this */
389 + if (!cmd->mrq->stop)
390 + /* multiblock no stop */
391 + fire |= GLAMO_FIRE_MMC_CC_MBRNS;
393 + /* multiblock with stop */
394 + fire |= GLAMO_FIRE_MMC_CC_MBRS;
396 + case MMC_WRITE_BLOCK:
397 + fire |= GLAMO_FIRE_MMC_CC_SBW; /* single block write */
399 + case MMC_WRITE_MULTIPLE_BLOCK:
400 + if (cmd->mrq->stop)
401 + /* multiblock with stop */
402 + fire |= GLAMO_FIRE_MMC_CC_MBWS;
404 + /* multiblock NO stop-- 'RESERVED'? */
405 + fire |= GLAMO_FIRE_MMC_CC_MBWNS;
407 + case MMC_STOP_TRANSMISSION:
408 + fire |= GLAMO_FIRE_MMC_CC_STOP; /* STOP */
411 + fire |= GLAMO_FIRE_MMC_CC_BASIC; /* "basic command" */
414 + /* enforce timeout */
416 + if (cmd->data->timeout_clks)
417 + writew_dly(cmd->data->timeout_clks >> 4, /* / 16 clks */
418 + host->base + GLAMO_REG_MMC_TIMEOUT);
420 + writew_dly(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT);
422 + writew(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT);
424 + /* Generate interrupt on txfer; drive strength max */
425 + writew_dly((readw_dly(host->base + GLAMO_REG_MMC_BASIC) & 0xfe) |
426 + 0x0800 | GLAMO_BASIC_MMC_NO_CLK_RD_WAIT |
427 + GLAMO_BASIC_MMC_EN_COMPL_INT |
428 + GLAMO_BASIC_MMC_EN_DR_STR0 |
429 + GLAMO_BASIC_MMC_EN_DR_STR1,
430 + host->base + GLAMO_REG_MMC_BASIC);
432 + /* send the command out on the wire */
433 + /* dev_info(&host->pdev->dev, "Using FIRE %04X\n", fire); */
434 + writew_dly(fire, host->base + GLAMO_REG_MMC_CMD_FIRE);
439 +static int glamo_mci_prepare_pio(struct glamo_mci_host *host,
440 + struct mmc_data *data)
443 + * the S-Media-internal RAM offset for our MMC buffer
444 + * Read is halfway up the buffer and write is at the start
446 + if (data->flags & MMC_DATA_READ) {
447 + writew_dly((u16)(GLAMO_FB_SIZE + (RESSIZE(host->mem_data) / 2)),
448 + host->base + GLAMO_REG_MMC_WDATADS1);
449 + writew_dly((u16)((GLAMO_FB_SIZE +
450 + (RESSIZE(host->mem_data) / 2)) >> 16),
451 + host->base + GLAMO_REG_MMC_WDATADS2);
453 + writew_dly((u16)GLAMO_FB_SIZE, host->base +
454 + GLAMO_REG_MMC_RDATADS1);
455 + writew_dly((u16)(GLAMO_FB_SIZE >> 16), host->base +
456 + GLAMO_REG_MMC_RDATADS2);
459 + /* set up the block info */
460 + writew_dly(data->blksz, host->base + GLAMO_REG_MMC_DATBLKLEN);
461 + writew_dly(data->blocks, host->base + GLAMO_REG_MMC_DATBLKCNT);
462 + dev_dbg(&host->pdev->dev, "(blksz=%d, count=%d)\n",
463 + data->blksz, data->blocks);
464 + host->pio_sgptr = 0;
465 + host->pio_words = 0;
466 + host->pio_count = 0;
467 + host->pio_active = 0;
468 + /* if write, prep the write into the shared RAM before the command */
469 + if (data->flags & MMC_DATA_WRITE) {
470 + host->pio_active = XFER_WRITE;
471 + return do_pio_write(host);
473 + host->pio_active = XFER_READ;
477 +static void glamo_mci_send_request(struct mmc_host *mmc)
479 + struct glamo_mci_host *host = mmc_priv(mmc);
480 + struct mmc_request *mrq = host->mrq;
481 + struct mmc_command *cmd = host->cmd_is_stop ? mrq->stop : mrq->cmd;
482 + u16 * pu16 = (u16 *)&cmd->resp[0];
483 + u16 * reg_resp = (u16 *)(host->base + GLAMO_REG_MMC_CMD_RSP1);
489 + * somehow 2.6.24 MCI manages to issue MMC_WRITE_BLOCK *without* the
490 + * MMC_DATA_WRITE flag, WTF? Work around the madness.
492 + if (cmd->opcode == MMC_WRITE_BLOCK)
494 + mrq->data->flags |= MMC_DATA_WRITE;
496 + /* this guy has data to read/write? */
497 + if ((!host->cmd_is_stop) && cmd->data) {
500 + res = glamo_mci_prepare_pio(host, cmd->data);
503 + cmd->data->error = -EIO;
504 + mmc_request_done(mmc, mrq);
509 + dev_dbg(&host->pdev->dev,"cmd 0x%x, "
510 + "arg 0x%x data=%p mrq->stop=%p flags 0x%x\n",
511 + cmd->opcode, cmd->arg, cmd->data, cmd->mrq->stop,
514 + if (glamo_mci_send_command(host, cmd))
517 + * we must spin until response is ready or timed out
518 + * -- we don't get interrupts unless there is a bulk rx
521 + status = readw_dly(host->base + GLAMO_REG_MMC_RB_STAT1);
522 + while ((((status >> 15) & 1) != (host->ccnt & 1)) ||
523 + (!(status & (GLAMO_STAT1_MMC_RB_RRDY |
524 + GLAMO_STAT1_MMC_RTOUT |
525 + GLAMO_STAT1_MMC_DTOUT |
526 + GLAMO_STAT1_MMC_BWERR |
527 + GLAMO_STAT1_MMC_BRERR))));
529 + if (status & (GLAMO_STAT1_MMC_RTOUT |
530 + GLAMO_STAT1_MMC_DTOUT))
531 + cmd->error = -ETIMEDOUT;
532 + if (status & (GLAMO_STAT1_MMC_BWERR |
533 + GLAMO_STAT1_MMC_BRERR))
534 + cmd->error = -EILSEQ;
536 + if (host->cmd_is_stop)
540 + dev_err(&host->pdev->dev, "Error after cmd: 0x%x\n", status);
544 + * mangle the response registers in two different exciting
545 + * undocumented ways discovered by trial and error
547 + if (mmc_resp_type(cmd) == MMC_RSP_R2)
548 + /* grab the response */
549 + for (n = 0; n < 8; n++) /* super mangle power 1 */
550 + pu16[n ^ 6] = readw_dly(®_resp[n]);
552 + for (n = 0; n < 3; n++) /* super mangle power 2 */
553 + pu16[n] = (readw_dly(®_resp[n]) >> 8) |
554 + (readw_dly(®_resp[n + 1]) << 8);
556 + * if we don't have bulk data to take care of, we're done
560 + if (!(cmd->data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)))
563 + * Otherwise can can use the interrupt as async completion --
564 + * if there is read data coming, or we wait for write data to complete,
565 + * exit without mmc_request_done() as the payload interrupt
568 + dev_dbg(&host->pdev->dev, "Waiting for payload data\n");
570 + * if the glamo INT# line isn't wired (*cough* it can happen)
571 + * I'm afraid we have to spin on the IRQ status bit and "be
572 + * our own INT# line"
574 + if (!glamo_mci_def_pdata.pglamo->irq_works) {
575 + /* we have faith we will get an "interrupt"... */
576 + while (!(readw_dly(glamo_mci_def_pdata.pglamo->base +
577 + GLAMO_REG_IRQ_STATUS) & GLAMO_IRQ_MMC))
579 + /* yay we are an interrupt controller! -- call the ISR */
580 + glamo_mci_irq(IRQ_GLAMO(GLAMO_IRQIDX_MMC),
581 + irq_desc + IRQ_GLAMO(GLAMO_IRQIDX_MMC));
586 + host->complete_what = COMPLETION_NONE;
588 + mmc_request_done(host->mmc, cmd->mrq);
591 +static void glamo_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
593 + struct glamo_mci_host *host = mmc_priv(mmc);
595 + host->cmd_is_stop = 0;
597 + glamo_mci_send_request(mmc);
600 +static void glamo_mci_reset(struct glamo_mci_host *host)
602 + /* reset MMC controller */
603 + writew_dly(GLAMO_CLOCK_MMC_RESET | GLAMO_CLOCK_MMC_DG_TCLK |
604 + GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK |
605 + GLAMO_CLOCK_MMC_EN_M9CLK,
606 + glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_MMC);
608 + /* and disable reset */
609 + writew_dly(GLAMO_CLOCK_MMC_DG_TCLK |
610 + GLAMO_CLOCK_MMC_EN_TCLK | GLAMO_CLOCK_MMC_DG_M9CLK |
611 + GLAMO_CLOCK_MMC_EN_M9CLK,
612 + glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_MMC);
615 +static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
617 + struct glamo_mci_host *host = mmc_priv(mmc);
622 + switch(ios->power_mode) {
625 + if (host->power_mode_current != MMC_POWER_OFF)
627 + if (host->vdd_current != ios->vdd) {
628 + host->pdata->glamo_set_mci_power(ios->power_mode,
630 + host->vdd_current = ios->vdd;
632 + glamo_engine_enable(glamo_mci_def_pdata.pglamo,
634 + glamo_mci_reset(host);
637 + case MMC_POWER_OFF:
639 + if (host->power_mode_current == MMC_POWER_OFF)
641 + glamo_engine_disable(glamo_mci_def_pdata.pglamo,
643 + host->pdata->glamo_set_mci_power(MMC_POWER_OFF, 0);
644 + host->vdd_current = -1;
647 + host->power_mode_current = ios->power_mode;
650 +/* if (ios->clock) { */
651 + for (mci_psc = 0; mci_psc < 256; mci_psc++) {
652 + host->real_rate = host->clk_rate / (mci_psc + 1);
653 + if (host->real_rate <= ios->clock)
658 + host->clk_div = mci_psc;
659 + /* set the nearest prescaler factor
661 + * register shared with SCLK divisor -- no chance of race because
662 + * we don't use sensor interface
664 + writew_dly((readw(glamo_mci_def_pdata.pglamo->base +
665 + GLAMO_REG_CLOCK_GEN8) & 0xff00) | host->clk_div,
666 + glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN8);
667 + /* enable clock to divider input */
668 + writew_dly(readw(glamo_mci_def_pdata.pglamo->base +
669 + GLAMO_REG_CLOCK_GEN5_1) | GLAMO_CLOCK_GEN51_EN_DIV_TCLK,
670 + glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1);
672 + } else { /* stop clock */
673 + host->real_rate = 0;
674 + /* remove clock from divider input */
675 + writew(readw(glamo_mci_def_pdata.pglamo->base +
676 + GLAMO_REG_CLOCK_GEN5_1) & (~GLAMO_CLOCK_GEN51_EN_DIV_TCLK),
677 + glamo_mci_def_pdata.pglamo->base + GLAMO_REG_CLOCK_GEN5_1);
680 + if ((ios->power_mode == MMC_POWER_ON) ||
681 + (ios->power_mode == MMC_POWER_UP)) {
682 + dev_info(&host->pdev->dev,
683 + "powered (vdd = %d) clk: %lukHz div=%d (req: %ukHz). "
684 + "Bus width=%d\n",ios->vdd,
685 + host->real_rate / 1000, mci_psc,
686 + ios->clock / 1000, ios->bus_width);
688 + dev_info(&host->pdev->dev, "glamo_mci_set_ios: power down.\n");
690 + /* set bus width */
691 + host->bus_width = ios->bus_width;
692 + if (host->bus_width == MMC_BUS_WIDTH_4)
693 + n = GLAMO_BASIC_MMC_EN_4BIT_DATA;
694 + writew_dly((readw_dly(host->base + GLAMO_REG_MMC_BASIC) &
695 + (~GLAMO_BASIC_MMC_EN_4BIT_DATA)) | n,
696 + host->base + GLAMO_REG_MMC_BASIC);
701 + * no physical write protect supported by us
703 +static int glamo_mci_get_ro(struct mmc_host *mmc)
708 +static struct mmc_host_ops glamo_mci_ops = {
709 + .request = glamo_mci_request,
710 + .set_ios = glamo_mci_set_ios,
711 + .get_ro = glamo_mci_get_ro,
714 +static int glamo_mci_probe(struct platform_device *pdev)
716 + struct mmc_host *mmc;
717 + struct glamo_mci_host *host;
720 + dev_info(&pdev->dev, "glamo_mci driver (C)2007 OpenMoko, Inc\n");
722 + mmc = mmc_alloc_host(sizeof(struct glamo_mci_host), &pdev->dev);
728 + host = mmc_priv(mmc);
731 + host->pdata = &glamo_mci_def_pdata;
732 + host->power_mode_current = MMC_POWER_OFF;
734 + host->complete_what = COMPLETION_NONE;
735 + host->pio_active = XFER_NONE;
737 + spin_lock_init(&host->complete_lock);
739 + host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
741 + dev_err(&pdev->dev,
742 + "failed to get io memory region resouce.\n");
745 + goto probe_free_host;
748 + host->mem = request_mem_region(host->mem->start,
749 + RESSIZE(host->mem), pdev->name);
752 + dev_err(&pdev->dev, "failed to request io memory region.\n");
754 + goto probe_free_host;
757 + host->base = ioremap(host->mem->start, RESSIZE(host->mem));
759 + dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
761 + goto probe_free_mem_region;
764 + /* set the handler for our bit of the shared chip irq register */
765 + set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_MMC), glamo_mci_irq);
766 + /* stash host as our handler's private data */
767 + set_irq_data(IRQ_GLAMO(GLAMO_IRQIDX_MMC), host);
769 + /* Get ahold of our data buffer we use for data in and out on MMC */
770 + host->mem_data = platform_get_resource(pdev, IORESOURCE_MEM, 1);
771 + if (!host->mem_data) {
772 + dev_err(&pdev->dev,
773 + "failed to get io memory region resource.\n");
775 + goto probe_iounmap;
778 + host->mem_data = request_mem_region(host->mem_data->start,
779 + RESSIZE(host->mem_data), pdev->name);
781 + if (!host->mem_data) {
782 + dev_err(&pdev->dev, "failed to request io memory region.\n");
784 + goto probe_iounmap;
786 + host->base_data = ioremap(host->mem_data->start,
787 + RESSIZE(host->mem_data));
788 + host->data_max_size = RESSIZE(host->mem_data);
790 + if (host->base_data == 0) {
791 + dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
793 + goto probe_free_mem_region_data;
796 + host->vdd_current = 0;
797 + host->clk_rate = 50000000; /* really it's 49152000 */
798 + host->clk_div = 16;
800 + /* explain our host controller capabilities */
801 + mmc->ops = &glamo_mci_ops;
802 + mmc->ocr_avail = host->pdata->ocr_avail;
803 + mmc->caps = MMC_CAP_4_BIT_DATA |
804 + MMC_CAP_MULTIWRITE |
805 + MMC_CAP_MMC_HIGHSPEED |
806 + MMC_CAP_SD_HIGHSPEED;
807 + mmc->f_min = host->clk_rate / 256;
809 + * held at /4 due to concerns of 100R recommended series resistor
810 + * allows 16MHz @ 4-bit --> 8MBytes/sec raw
812 + mmc->f_max = host->clk_rate / 3;
814 + mmc->max_blk_count = (1 << 16) - 1; /* GLAMO_REG_MMC_RB_BLKCNT */
815 + mmc->max_blk_size = (1 << 12) - 1; /* GLAMO_REG_MMC_RB_BLKLEN */
816 + mmc->max_req_size = RESSIZE(host->mem_data) / 2;
817 + mmc->max_seg_size = mmc->max_req_size;
818 + mmc->max_phys_segs = 1; /* hw doesn't talk about segs??? */
819 + mmc->max_hw_segs = 1;
821 + dev_info(&host->pdev->dev, "probe: mapped mci_base:%p irq:%u.\n",
822 + host->base, host->irq);
824 + if ((ret = mmc_add_host(mmc))) {
825 + dev_err(&pdev->dev, "failed to add mmc host.\n");
826 + goto probe_free_mem_region_data;
829 + platform_set_drvdata(pdev, mmc);
831 + dev_info(&pdev->dev,"initialisation done.\n");
834 + probe_free_mem_region_data:
835 + release_mem_region(host->mem_data->start, RESSIZE(host->mem_data));
838 + iounmap(host->base);
840 + probe_free_mem_region:
841 + release_mem_region(host->mem->start, RESSIZE(host->mem));
844 + mmc_free_host(mmc);
849 +static int glamo_mci_remove(struct platform_device *pdev)
851 + struct mmc_host *mmc = platform_get_drvdata(pdev);
852 + struct glamo_mci_host *host = mmc_priv(mmc);
854 + mmc_remove_host(mmc);
855 + /* stop using our handler, revert it to default */
856 + set_irq_handler(IRQ_GLAMO(GLAMO_IRQIDX_MMC), handle_level_irq);
857 + iounmap(host->base);
858 + iounmap(host->base_data);
859 + release_mem_region(host->mem->start, RESSIZE(host->mem));
860 + release_mem_region(host->mem_data->start, RESSIZE(host->mem_data));
861 + mmc_free_host(mmc);
863 + glamo_engine_disable(glamo_mci_def_pdata.pglamo, GLAMO_ENGINE_MMC);
870 +static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state)
872 + struct mmc_host *mmc = platform_get_drvdata(dev);
874 + return mmc_suspend_host(mmc, state);
877 +static int glamo_mci_resume(struct platform_device *dev)
879 + struct mmc_host *mmc = platform_get_drvdata(dev);
881 + return mmc_resume_host(mmc);
884 +#else /* CONFIG_PM */
885 +#define glamo_mci_suspend NULL
886 +#define glamo_mci_resume NULL
887 +#endif /* CONFIG_PM */
890 +static struct platform_driver glamo_mci_driver =
892 + .driver.name = "glamo-mci",
893 + .probe = glamo_mci_probe,
894 + .remove = glamo_mci_remove,
895 + .suspend = glamo_mci_suspend,
896 + .resume = glamo_mci_resume,
899 +static int __init glamo_mci_init(void)
901 + platform_driver_register(&glamo_mci_driver);
905 +static void __exit glamo_mci_exit(void)
907 + platform_driver_unregister(&glamo_mci_driver);
910 +module_init(glamo_mci_init);
911 +module_exit(glamo_mci_exit);
913 +MODULE_DESCRIPTION("Glamo MMC/SD Card Interface driver");
914 +MODULE_LICENSE("GPL");
915 +MODULE_AUTHOR("Andy Green <andy@openmoko.com>");
916 diff --git a/drivers/mfd/glamo/glamo-mci.h b/drivers/mfd/glamo/glamo-mci.h
918 index 0000000..40c3e24
920 +++ b/drivers/mfd/glamo/glamo-mci.h
923 + * linux/drivers/mmc/host/glamo-mmc.h - GLAMO MCI driver
925 + * Copyright (C) 2007-2008 OpenMoko, Inc, Andy Green <andy@openmoko.com>
926 + * based on S3C MMC driver -->
927 + * Copyright (C) 2004-2006 Thomas Kleffel, All Rights Reserved.
929 + * This program is free software; you can redistribute it and/or modify
930 + * it under the terms of the GNU General Public License version 2 as
931 + * published by the Free Software Foundation.
935 +enum glamo_mci_waitfor {
937 + COMPLETION_FINALIZE,
938 + COMPLETION_CMDSENT,
940 + COMPLETION_XFERFINISH,
941 + COMPLETION_XFERFINISH_RSPFIN,
944 +struct glamo_mci_host {
945 + struct platform_device *pdev;
946 + struct glamo_mci_pdata *pdata;
947 + struct mmc_host *mmc;
948 + struct resource *mem;
949 + struct resource *mem_data;
951 + void __iomem *base;
952 + u16 __iomem *base_data;
958 + int power_mode_current;
959 + unsigned int vdd_current;
961 + unsigned long clk_rate;
962 + unsigned long clk_div;
963 + unsigned long real_rate;
969 + volatile int dmatogo;
971 + struct mmc_request *mrq;
974 + spinlock_t complete_lock;
975 + volatile enum glamo_mci_waitfor
978 + volatile int dma_complete;
980 + volatile u32 pio_sgptr;
981 + volatile u32 pio_words;
982 + volatile u32 pio_count;
983 + volatile u16 *pio_ptr;
986 +#define XFER_WRITE 2
987 + volatile u32 pio_active;
991 + char dbgmsg_cmd[301];
992 + char dbgmsg_dat[301];
993 + volatile char *status;
995 + unsigned int ccnt, dcnt;
996 + struct tasklet_struct pio_tasklet;
998 diff --git a/drivers/mfd/glamo/glamo-regs.h b/drivers/mfd/glamo/glamo-regs.h
999 index 151cd66..8f6c45c 100644
1000 --- a/drivers/mfd/glamo/glamo-regs.h
1001 +++ b/drivers/mfd/glamo/glamo-regs.h
1002 @@ -150,16 +150,28 @@ enum glamo_reg_mem_dram2 {
1003 GLAMO_MEM_DRAM2_DEEP_PWRDOWN = (1 << 12),
1006 +enum glamo_irq_index {
1007 + GLAMO_IRQIDX_HOSTBUS = 0,
1008 + GLAMO_IRQIDX_JPEG = 1,
1009 + GLAMO_IRQIDX_MPEG = 2,
1010 + GLAMO_IRQIDX_MPROC1 = 3,
1011 + GLAMO_IRQIDX_MPROC0 = 4,
1012 + GLAMO_IRQIDX_CMDQUEUE = 5,
1013 + GLAMO_IRQIDX_2D = 6,
1014 + GLAMO_IRQIDX_MMC = 7,
1015 + GLAMO_IRQIDX_RISC = 8,
1019 - GLAMO_IRQ_HOSTBUS = 0x0001,
1020 - GLAMO_IRQ_JPEG = 0x0002,
1021 - GLAMO_IRQ_MPEG = 0x0004,
1022 - GLAMO_IRQ_MPROC1 = 0x0008,
1023 - GLAMO_IRQ_MPROC0 = 0x0010,
1024 - GLAMO_IRQ_CMDQUEUE = 0x0020,
1025 - GLAMO_IRQ_2D = 0x0040,
1026 - GLAMO_IRQ_MMC = 0x0080,
1027 - GLAMO_IRQ_RISC = 0x0100,
1028 + GLAMO_IRQ_HOSTBUS = (1 << GLAMO_IRQIDX_HOSTBUS),
1029 + GLAMO_IRQ_JPEG = (1 << GLAMO_IRQIDX_JPEG),
1030 + GLAMO_IRQ_MPEG = (1 << GLAMO_IRQIDX_MPEG),
1031 + GLAMO_IRQ_MPROC1 = (1 << GLAMO_IRQIDX_MPROC1),
1032 + GLAMO_IRQ_MPROC0 = (1 << GLAMO_IRQIDX_MPROC0),
1033 + GLAMO_IRQ_CMDQUEUE = (1 << GLAMO_IRQIDX_CMDQUEUE),
1034 + GLAMO_IRQ_2D = (1 << GLAMO_IRQIDX_2D),
1035 + GLAMO_IRQ_MMC = (1 << GLAMO_IRQIDX_MMC),
1036 + GLAMO_IRQ_RISC = (1 << GLAMO_IRQIDX_RISC),
1039 enum glamo_reg_clock_host {
1040 @@ -197,6 +209,145 @@ enum glamo_reg_clock_mmc {
1041 GLAMO_CLOCK_MMC_RESET = 0x1000,
1044 +enum glamo_reg_basic_mmc {
1045 + /* set to disable CRC error rejection */
1046 + GLAMO_BASIC_MMC_DISABLE_CRC = 0x0001,
1047 + /* enable completion interrupt */
1048 + GLAMO_BASIC_MMC_EN_COMPL_INT = 0x0002,
1049 + /* stop MMC clock while enforced idle waiting for data from card */
1050 + GLAMO_BASIC_MMC_NO_CLK_RD_WAIT = 0x0004,
1051 + /* 0 = 1-bit bus to card, 1 = use 4-bit bus (has to be negotiated) */
1052 + GLAMO_BASIC_MMC_EN_4BIT_DATA = 0x0008,
1053 + /* enable 75K pullups on D3..D0 */
1054 + GLAMO_BASIC_MMC_EN_DATA_PUPS = 0x0010,
1055 + /* enable 75K pullup on CMD */
1056 + GLAMO_BASIC_MMC_EN_CMD_PUP = 0x0020,
1057 + /* IO drive strength 00=weak -> 11=strongest */
1058 + GLAMO_BASIC_MMC_EN_DR_STR0 = 0x0040,
1059 + GLAMO_BASIC_MMC_EN_DR_STR1 = 0x0080,
1060 + /* TCLK delay stage A, 0000 = 500ps --> 1111 = 8ns */
1061 + GLAMO_BASIC_MMC_EN_TCLK_DLYA0 = 0x0100,
1062 + GLAMO_BASIC_MMC_EN_TCLK_DLYA1 = 0x0200,
1063 + GLAMO_BASIC_MMC_EN_TCLK_DLYA2 = 0x0400,
1064 + GLAMO_BASIC_MMC_EN_TCLK_DLYA3 = 0x0800,
1065 + /* TCLK delay stage B (cumulative), 0000 = 500ps --> 1111 = 8ns */
1066 + GLAMO_BASIC_MMC_EN_TCLK_DLYB0 = 0x1000,
1067 + GLAMO_BASIC_MMC_EN_TCLK_DLYB1 = 0x2000,
1068 + GLAMO_BASIC_MMC_EN_TCLK_DLYB2 = 0x4000,
1069 + GLAMO_BASIC_MMC_EN_TCLK_DLYB3 = 0x8000,
1072 +enum glamo_reg_stat1_mmc {
1073 + /* command "counter" (really: toggle) */
1074 + GLAMO_STAT1_MMC_CMD_CTR = 0x8000,
1075 + /* engine is idle */
1076 + GLAMO_STAT1_MMC_IDLE = 0x4000,
1077 + /* readback response is ready */
1078 + GLAMO_STAT1_MMC_RB_RRDY = 0x0200,
1079 + /* readback data is ready */
1080 + GLAMO_STAT1_MMC_RB_DRDY = 0x0100,
1081 + /* no response timeout */
1082 + GLAMO_STAT1_MMC_RTOUT = 0x0020,
1083 + /* no data timeout */
1084 + GLAMO_STAT1_MMC_DTOUT = 0x0010,
1085 + /* CRC error on block write */
1086 + GLAMO_STAT1_MMC_BWERR = 0x0004,
1087 + /* CRC error on block read */
1088 + GLAMO_STAT1_MMC_BRERR = 0x0002
1091 +enum glamo_reg_fire_mmc {
1092 + /* command "counter" (really: toggle)
1093 + * the STAT1 register reflects this so you can ensure you don't look
1094 + * at status for previous command
1096 + GLAMO_FIRE_MMC_CMD_CTR = 0x8000,
1097 + /* sets kind of response expected */
1098 + GLAMO_FIRE_MMC_RES_MASK = 0x0700,
1099 + /* sets command type */
1100 + GLAMO_FIRE_MMC_TYP_MASK = 0x00C0,
1101 + /* sets command class */
1102 + GLAMO_FIRE_MMC_CLS_MASK = 0x000F,
1105 +enum glamo_fire_mmc_response_types {
1106 + GLAMO_FIRE_MMC_RSPT_R1 = 0x0000,
1107 + GLAMO_FIRE_MMC_RSPT_R1b = 0x0100,
1108 + GLAMO_FIRE_MMC_RSPT_R2 = 0x0200,
1109 + GLAMO_FIRE_MMC_RSPT_R3 = 0x0300,
1110 + GLAMO_FIRE_MMC_RSPT_R4 = 0x0400,
1111 + GLAMO_FIRE_MMC_RSPT_R5 = 0x0500,
1114 +enum glamo_fire_mmc_command_types {
1115 + /* broadcast, no response */
1116 + GLAMO_FIRE_MMC_CMDT_BNR = 0x0000,
1117 + /* broadcast, with response */
1118 + GLAMO_FIRE_MMC_CMDT_BR = 0x0040,
1119 + /* addressed, no data */
1120 + GLAMO_FIRE_MMC_CMDT_AND = 0x0080,
1121 + /* addressed, with data */
1122 + GLAMO_FIRE_MMC_CMDT_AD = 0x00C0,
1125 +enum glamo_fire_mmc_command_class {
1126 + /* "Stream Read" */
1127 + GLAMO_FIRE_MMC_CC_STRR = 0x0000,
1128 + /* Single Block Read */
1129 + GLAMO_FIRE_MMC_CC_SBR = 0x0001,
1130 + /* Multiple Block Read With Stop */
1131 + GLAMO_FIRE_MMC_CC_MBRS = 0x0002,
1132 + /* Multiple Block Read No Stop */
1133 + GLAMO_FIRE_MMC_CC_MBRNS = 0x0003,
1134 + /* RESERVED for "Stream Write" */
1135 + GLAMO_FIRE_MMC_CC_STRW = 0x0004,
1136 + /* "Stream Write" */
1137 + GLAMO_FIRE_MMC_CC_SBW = 0x0005,
1138 + /* RESERVED for Multiple Block Write With Stop */
1139 + GLAMO_FIRE_MMC_CC_MBWS = 0x0006,
1140 + /* Multiple Block Write No Stop */
1141 + GLAMO_FIRE_MMC_CC_MBWNS = 0x0007,
1142 + /* STOP command */
1143 + GLAMO_FIRE_MMC_CC_STOP = 0x0008,
1144 + /* Cancel on Running Command */
1145 + GLAMO_FIRE_MMC_CC_CANCL = 0x0009,
1146 + /* "Basic Command" */
1147 + GLAMO_FIRE_MMC_CC_BASIC = 0x000a,
1150 +/* these are offsets from the start of the MMC register region */
1151 +enum glamo_register_mmc {
1152 + /* MMC command, b15..8 = cmd arg b7..0; b7..1 = CRC; b0 = end bit */
1153 + GLAMO_REG_MMC_CMD_REG1 = 0x00,
1154 + /* MMC command, b15..0 = cmd arg b23 .. 8 */
1155 + GLAMO_REG_MMC_CMD_REG2 = 0x02,
1156 + /* MMC command, b15=start, b14=transmission,
1157 + * b13..8=cmd idx, b7..0=cmd arg b31..24
1159 + GLAMO_REG_MMC_CMD_REG3 = 0x04,
1160 + GLAMO_REG_MMC_CMD_FIRE = 0x06,
1161 + GLAMO_REG_MMC_CMD_RSP1 = 0x10,
1162 + GLAMO_REG_MMC_CMD_RSP2 = 0x12,
1163 + GLAMO_REG_MMC_CMD_RSP3 = 0x14,
1164 + GLAMO_REG_MMC_CMD_RSP4 = 0x16,
1165 + GLAMO_REG_MMC_CMD_RSP5 = 0x18,
1166 + GLAMO_REG_MMC_CMD_RSP6 = 0x1a,
1167 + GLAMO_REG_MMC_CMD_RSP7 = 0x1c,
1168 + GLAMO_REG_MMC_CMD_RSP8 = 0x1e,
1169 + GLAMO_REG_MMC_RB_STAT1 = 0x20,
1170 + GLAMO_REG_MMC_RB_BLKCNT = 0x22,
1171 + GLAMO_REG_MMC_RB_BLKLEN = 0x24,
1172 + GLAMO_REG_MMC_BASIC = 0x30,
1173 + GLAMO_REG_MMC_RDATADS1 = 0x34,
1174 + GLAMO_REG_MMC_RDATADS2 = 0x36,
1175 + GLAMO_REG_MMC_WDATADS1 = 0x38,
1176 + GLAMO_REG_MMC_WDATADS2 = 0x3a,
1177 + GLAMO_REG_MMC_DATBLKCNT = 0x3c,
1178 + GLAMO_REG_MMC_DATBLKLEN = 0x3e,
1179 + GLAMO_REG_MMC_TIMEOUT = 0x40,
1183 enum glamo_reg_clock_isp {
1184 GLAMO_CLOCK_ISP_DG_I1CLK = 0x0001,
1185 GLAMO_CLOCK_ISP_EN_I1CLK = 0x0002,