changed Makefile and profiles, added patches for kernel 2.6.24
[openwrt.git] / target / linux / s3c24xx / patches-2.6.24 / 1034-glamo-mmc.patch.patch
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
5
6 ---
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
16
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.
24  
25 +config MFD_GLAMO_MCI
26 +       tristate "Glamo S3C SD/MMC Card Interface support"
27 +       depends on MFD_GLAMO && MMC
28 +       help
29 +         This selects a driver for the MCI interface found in
30 +         the S-Media GLAMO chip, as used in OpenMoko
31 +         neo1973 GTA-02.
32 +
33 +         If unsure, say N.
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
40  
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
44  
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)
50  {
51         spin_lock(&glamo->lock);
52         switch (engine) {
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);
68 +*/
69 +               break;
70         default:
71                 break;
72         }
73 diff --git a/drivers/mfd/glamo/glamo-mci.c b/drivers/mfd/glamo/glamo-mci.c
74 new file mode 100644
75 index 0000000..f559e5e
76 --- /dev/null
77 +++ b/drivers/mfd/glamo/glamo-mci.c
78 @@ -0,0 +1,837 @@
79 +/*
80 + *  linux/drivers/mmc/host/glamo-mmc.c - Glamo MMC driver
81 + *
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>
85 + *
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.
89 + */
90 +
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>
101 +
102 +#include <asm/dma.h>
103 +#include <asm/dma-mapping.h>
104 +#include <asm/io.h>
105 +
106 +#include "glamo-mci.h"
107 +#include "glamo-core.h"
108 +#include "glamo-regs.h"
109 +
110 +/* from glamo-core.c */
111 +extern struct glamo_mci_pdata glamo_mci_def_pdata;
112 +
113 +
114 +#define DRIVER_NAME "glamo-mci"
115 +#define RESSIZE(ressource) (((ressource)->end - (ressource)->start) + 1)
116 +
117 +static void glamo_mci_send_request(struct mmc_host *mmc);
118 +
119 +unsigned char CRC7(u8 * pu8, int cnt)
120 +{
121 +       u8 crc = 0;
122 +
123 +       while (cnt--) {
124 +               int n;
125 +               u8 d = *pu8++;
126 +               for (n = 0; n < 8; n++) {
127 +                       crc <<= 1;
128 +                       if ((d & 0x80) ^ (crc & 0x80))
129 +                               crc ^= 0x09;
130 +                       d <<= 1;
131 +               }
132 +       }
133 +       return (crc << 1) | 1;
134 +}
135 +
136 +/* these _dly versions account for the dead time rules for reg access */
137 +static u16 readw_dly(u16 __iomem * pu16)
138 +{
139 +       glamo_reg_access_delay();
140 +       return readw(pu16);
141 +}
142 +
143 +static void writew_dly(u16 val, u16 __iomem * pu16)
144 +{
145 +       glamo_reg_access_delay();
146 +       writew(val, pu16);
147 +}
148 +
149 +static int get_data_buffer(struct glamo_mci_host *host,
150 +                          volatile u32 *words, volatile u16 **pointer)
151 +{
152 +       struct scatterlist *sg;
153 +
154 +       *words = 0;
155 +       *pointer = NULL;
156 +
157 +       if (host->pio_active == XFER_NONE)
158 +               return -EINVAL;
159 +
160 +       if ((!host->mrq) || (!host->mrq->data))
161 +               return -EINVAL;
162 +
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);
166 +               return -EBUSY;
167 +       }
168 +       sg = &host->mrq->data->sg[host->pio_sgptr];
169 +
170 +       *words = sg->length >> 1; /* we are working with a 16-bit data bus */
171 +       *pointer = page_address(sg_page(sg)) + sg->offset;
172 +
173 +       BUG_ON(((long)(*pointer)) & 1);
174 +
175 +       host->pio_sgptr++;
176 +
177 +       /* dev_info(&host->pdev->dev, "new buffer (%i/%i)\n",
178 +             host->pio_sgptr, host->mrq->data->sg_len); */
179 +       return 0;
180 +}
181 +
182 +static void do_pio_read(struct glamo_mci_host *host)
183 +{
184 +       int res;
185 +       u16 __iomem *from_ptr = host->base_data + (RESSIZE(host->mem_data) /
186 +                                                             sizeof(u16) / 2);
187 +#ifdef DEBUG
188 +       u16 * block;
189 +#endif
190 +
191 +       while (1) {
192 +               res = get_data_buffer(host, &host->pio_words, &host->pio_ptr);
193 +               if (res) {
194 +                       host->pio_active = XFER_NONE;
195 +                       host->complete_what = COMPLETION_FINALIZE;
196 +
197 +                       dev_dbg(&host->pdev->dev, "pio_read(): "
198 +                               "complete (no more data).\n");
199 +                       return;
200 +               }
201 +
202 +               dev_dbg(&host->pdev->dev, "pio_read(): host->pio_words: %d\n",
203 +                               host->pio_words);
204 +
205 +               host->pio_count += host->pio_words << 1;
206 +
207 +#ifdef DEBUG
208 +               block = (u16 *)host->pio_ptr;
209 +               res = host->pio_words << 1;
210 +#endif
211 +               while (host->pio_words--)
212 +                       *host->pio_ptr++ = *from_ptr++;
213 +#ifdef DEBUG
214 +               print_hex_dump(KERN_DEBUG, "", DUMP_PREFIX_OFFSET, 16, 1,
215 +                              (void *)block, res, 1);
216 +#endif
217 +       }
218 +}
219 +
220 +static int do_pio_write(struct glamo_mci_host *host)
221 +{
222 +       int res = 0;
223 +       volatile u16 __iomem *to_ptr = host->base_data;
224 +       int err = 0;
225 +
226 +       dev_dbg(&host->pdev->dev, "pio_write():\n");
227 +       while (!res) {
228 +               res = get_data_buffer(host, &host->pio_words, &host->pio_ptr);
229 +               if (res)
230 +                       continue;
231 +
232 +               dev_dbg(&host->pdev->dev, "pio_write():new source: [%i]@[%p]\n",
233 +                       host->pio_words, host->pio_ptr);
234 +
235 +               host->pio_count += host->pio_words << 1;
236 +               while (host->pio_words--)
237 +                       writew(*host->pio_ptr++, to_ptr++);
238 +       }
239 +
240 +       dev_dbg(&host->pdev->dev, "pio_write(): complete\n");
241 +       host->pio_active = XFER_NONE;
242 +       return err;
243 +}
244 +
245 +static void glamo_mci_irq(unsigned int irq, struct irq_desc *desc)
246 +{
247 +       struct glamo_mci_host *host = (struct glamo_mci_host *)
248 +                                     desc->handler_data;
249 +       u16 status;
250 +       struct mmc_command *cmd;
251 +       unsigned long iflags;
252 +
253 +       if (!host)
254 +               return;
255 +       if (!host->mrq)
256 +               return;
257 +       cmd = host->mrq->cmd;
258 +       if (!cmd)
259 +               return;
260 +
261 +       spin_lock_irqsave(&host->complete_lock, iflags);
262 +
263 +       status = readw_dly(host->base + GLAMO_REG_MMC_RB_STAT1);
264 +
265 +       /* ack this interrupt source */
266 +       writew(GLAMO_IRQ_MMC,
267 +              glamo_mci_def_pdata.pglamo->base + GLAMO_REG_IRQ_CLEAR);
268 +
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;
275 +       if (cmd->error) {
276 +               dev_err(&host->pdev->dev, "Error after cmd: 0x%x\n", status);
277 +               goto done;
278 +       }
279 +
280 +       if (host->pio_active == XFER_READ)
281 +               do_pio_read(host);
282 +
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);
286 +
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;
292 +       }
293 +done:
294 +       host->complete_what = COMPLETION_NONE;
295 +       host->mrq = NULL;
296 +       mmc_request_done(host->mmc, cmd->mrq);
297 +       spin_unlock_irqrestore(&host->complete_lock, iflags);
298 +}
299 +
300 +static int glamo_mci_send_command(struct glamo_mci_host *host,
301 +                                 struct mmc_command *cmd)
302 +{
303 +       u8 u8a[6];
304 +       u16 fire = 0;
305 +
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) {
309 +               host->mrq = NULL;
310 +               cmd->error = -EBUSY;
311 +               mmc_request_done(host->mmc, host->mrq);
312 +               return -EBUSY;
313 +       }
314 +
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 */
322 +
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);
327 +
328 +       /* command index toggle */
329 +       fire |= (host->ccnt & 1) << 12;
330 +
331 +       /* set type of command */
332 +       switch (mmc_cmd_type(cmd)) {
333 +       case MMC_CMD_BC:
334 +               fire |= GLAMO_FIRE_MMC_CMDT_BNR;
335 +               break;
336 +       case MMC_CMD_BCR:
337 +               fire |= GLAMO_FIRE_MMC_CMDT_BR;
338 +               break;
339 +       case MMC_CMD_AC:
340 +               fire |= GLAMO_FIRE_MMC_CMDT_AND;
341 +               break;
342 +       case MMC_CMD_ADTC:
343 +               fire |= GLAMO_FIRE_MMC_CMDT_AD;
344 +               break;
345 +       }
346 +       /*
347 +        * if it expects a response, set the type expected
348 +        *
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)
358 +        */
359 +       switch (mmc_resp_type(cmd)) {
360 +       case MMC_RSP_R6: /* same index as R7 and R1 */
361 +               fire |= GLAMO_FIRE_MMC_RSPT_R1;
362 +               break;
363 +       case MMC_RSP_R1B:
364 +               fire |= GLAMO_FIRE_MMC_RSPT_R1b;
365 +               break;
366 +       case MMC_RSP_R2:
367 +               fire |= GLAMO_FIRE_MMC_RSPT_R2;
368 +               break;
369 +       case MMC_RSP_R3:
370 +               fire |= GLAMO_FIRE_MMC_RSPT_R3;
371 +               break;
372 +       /* R4 and R5 supported by chip not defined in linux/mmc/core.h (sdio) */
373 +       }
374 +       /*
375 +        * From the command index, set up the command class in the host ctrllr
376 +        *
377 +        * missing guys present on chip but couldn't figure out how to use yet:
378 +        *     0x0 "stream read"
379 +        *     0x9 "cancel running command"
380 +        */
381 +       switch (cmd->opcode) {
382 +       case MMC_READ_SINGLE_BLOCK:
383 +               fire |= GLAMO_FIRE_MMC_CC_SBR; /* single block read */
384 +               break;
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;
392 +               else
393 +                        /* multiblock with stop */
394 +                       fire |= GLAMO_FIRE_MMC_CC_MBRS;
395 +               break;
396 +       case MMC_WRITE_BLOCK:
397 +               fire |= GLAMO_FIRE_MMC_CC_SBW; /* single block write */
398 +               break;
399 +       case MMC_WRITE_MULTIPLE_BLOCK:
400 +               if (cmd->mrq->stop)
401 +                        /* multiblock with stop */
402 +                       fire |= GLAMO_FIRE_MMC_CC_MBWS;
403 +               else
404 +                        /* multiblock NO stop-- 'RESERVED'? */
405 +                       fire |= GLAMO_FIRE_MMC_CC_MBWNS;
406 +               break;
407 +       case MMC_STOP_TRANSMISSION:
408 +               fire |= GLAMO_FIRE_MMC_CC_STOP; /* STOP */
409 +               break;
410 +       default:
411 +               fire |= GLAMO_FIRE_MMC_CC_BASIC; /* "basic command" */
412 +               break;
413 +       }
414 +       /* enforce timeout */
415 +       if (cmd->data) {
416 +               if (cmd->data->timeout_clks)
417 +                       writew_dly(cmd->data->timeout_clks >> 4, /* / 16 clks */
418 +                                       host->base + GLAMO_REG_MMC_TIMEOUT);
419 +               else
420 +                       writew_dly(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT);
421 +       } else
422 +               writew(0xfff, host->base + GLAMO_REG_MMC_TIMEOUT);
423 +
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);
431 +
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);
435 +       cmd->error = 0;
436 +       return 0;
437 +}
438 +
439 +static int glamo_mci_prepare_pio(struct glamo_mci_host *host,
440 +                                struct mmc_data *data)
441 +{
442 +       /*
443 +        * the S-Media-internal RAM offset for our MMC buffer
444 +        * Read is halfway up the buffer and write is at the start
445 +        */
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);
452 +       } else {
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);
457 +       }
458 +
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);
472 +       }
473 +       host->pio_active = XFER_READ;
474 +       return 0;
475 +}
476 +
477 +static void glamo_mci_send_request(struct mmc_host *mmc)
478 +{
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);
484 +       u16 status;
485 +       int n;
486 +
487 +       host->ccnt++;
488 +       /*
489 +        * somehow 2.6.24 MCI manages to issue MMC_WRITE_BLOCK *without* the
490 +        * MMC_DATA_WRITE flag, WTF?  Work around the madness.
491 +        */
492 +       if (cmd->opcode == MMC_WRITE_BLOCK)
493 +               if (mrq->data)
494 +                       mrq->data->flags |= MMC_DATA_WRITE;
495 +
496 +        /* this guy has data to read/write? */
497 +       if ((!host->cmd_is_stop) && cmd->data) {
498 +               int res;
499 +               host->dcnt++;
500 +               res = glamo_mci_prepare_pio(host, cmd->data);
501 +               if (res) {
502 +                       cmd->error = -EIO;
503 +                       cmd->data->error = -EIO;
504 +                       mmc_request_done(mmc, mrq);
505 +                       return;
506 +               }
507 +       }
508 +
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,
512 +                cmd->flags);
513 +
514 +       if (glamo_mci_send_command(host, cmd))
515 +               return;
516 +       /*
517 +        * we must spin until response is ready or timed out
518 +        * -- we don't get interrupts unless there is a bulk rx
519 +        */
520 +       do
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))));
528 +
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;
535 +
536 +       if (host->cmd_is_stop)
537 +               return;
538 +
539 +       if (cmd->error) {
540 +               dev_err(&host->pdev->dev, "Error after cmd: 0x%x\n", status);
541 +               goto done;
542 +       }
543 +       /*
544 +        * mangle the response registers in two different exciting
545 +        * undocumented ways discovered by trial and error
546 +        */
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(&reg_resp[n]);
551 +       else
552 +               for (n = 0; n < 3; n++) /* super mangle power 2 */
553 +                       pu16[n] = (readw_dly(&reg_resp[n]) >> 8) |
554 +                                 (readw_dly(&reg_resp[n + 1]) << 8);
555 +       /*
556 +        * if we don't have bulk data to take care of, we're done
557 +        */
558 +       if (!cmd->data)
559 +               goto done;
560 +       if (!(cmd->data->flags & (MMC_DATA_READ | MMC_DATA_WRITE)))
561 +               goto done;
562 +       /*
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
566 +        * will service it
567 +        */
568 +       dev_dbg(&host->pdev->dev, "Waiting for payload data\n");
569 +       /*
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"
573 +        */
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))
578 +                       ;
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));
582 +       }
583 +       return;
584 +
585 +done:
586 +       host->complete_what = COMPLETION_NONE;
587 +       host->mrq = NULL;
588 +       mmc_request_done(host->mmc, cmd->mrq);
589 +}
590 +
591 +static void glamo_mci_request(struct mmc_host *mmc, struct mmc_request *mrq)
592 +{
593 +       struct glamo_mci_host *host = mmc_priv(mmc);
594 +
595 +       host->cmd_is_stop = 0;
596 +       host->mrq = mrq;
597 +       glamo_mci_send_request(mmc);
598 +}
599 +
600 +static void glamo_mci_reset(struct glamo_mci_host *host)
601 +{
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);
607 +       msleep(1);
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);
613 +}
614 +
615 +static void glamo_mci_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
616 +{
617 +       struct glamo_mci_host *host = mmc_priv(mmc);
618 +       int mci_psc = 0;
619 +       int n = 0;
620 +
621 +       /* Set power */
622 +       switch(ios->power_mode) {
623 +       case MMC_POWER_ON:
624 +       case MMC_POWER_UP:
625 +               if (host->power_mode_current != MMC_POWER_OFF)
626 +                       break;
627 +               if (host->vdd_current != ios->vdd) {
628 +                       host->pdata->glamo_set_mci_power(ios->power_mode,
629 +                                                        ios->vdd);
630 +                       host->vdd_current = ios->vdd;
631 +               }
632 +               glamo_engine_enable(glamo_mci_def_pdata.pglamo,
633 +                                                       GLAMO_ENGINE_MMC);
634 +               glamo_mci_reset(host);
635 +               break;
636 +
637 +       case MMC_POWER_OFF:
638 +       default:
639 +               if (host->power_mode_current == MMC_POWER_OFF)
640 +                       break;
641 +               glamo_engine_disable(glamo_mci_def_pdata.pglamo,
642 +                                    GLAMO_ENGINE_MMC);
643 +               host->pdata->glamo_set_mci_power(MMC_POWER_OFF, 0);
644 +               host->vdd_current = -1;
645 +               break;
646 +       }
647 +       host->power_mode_current = ios->power_mode;
648 +
649 +        /* Set clock */
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)
654 +                       break;
655 +       }
656 +       if (mci_psc > 255)
657 +               mci_psc = 255;
658 +       host->clk_div = mci_psc;
659 +       /* set the nearest prescaler factor
660 +       *
661 +       * register shared with SCLK divisor -- no chance of race because
662 +       * we don't use sensor interface
663 +       */
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);
671 +#if 0
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);
678 +       }
679 +#endif
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);
687 +       } else
688 +               dev_info(&host->pdev->dev, "glamo_mci_set_ios: power down.\n");
689 +
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);
697 +}
698 +
699 +
700 +/*
701 + * no physical write protect supported by us
702 + */
703 +static int glamo_mci_get_ro(struct mmc_host *mmc)
704 +{
705 +       return 0;
706 +}
707 +
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,
712 +};
713 +
714 +static int glamo_mci_probe(struct platform_device *pdev)
715 +{
716 +       struct mmc_host         *mmc;
717 +       struct glamo_mci_host   *host;
718 +       int ret;
719 +
720 +       dev_info(&pdev->dev, "glamo_mci driver (C)2007 OpenMoko, Inc\n");
721 +
722 +       mmc = mmc_alloc_host(sizeof(struct glamo_mci_host), &pdev->dev);
723 +       if (!mmc) {
724 +               ret = -ENOMEM;
725 +               goto probe_out;
726 +       }
727 +
728 +       host = mmc_priv(mmc);
729 +       host->mmc = mmc;
730 +       host->pdev = pdev;
731 +       host->pdata = &glamo_mci_def_pdata;
732 +       host->power_mode_current = MMC_POWER_OFF;
733 +
734 +       host->complete_what = COMPLETION_NONE;
735 +       host->pio_active = XFER_NONE;
736 +
737 +       spin_lock_init(&host->complete_lock);
738 +
739 +       host->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
740 +       if (!host->mem) {
741 +               dev_err(&pdev->dev,
742 +                       "failed to get io memory region resouce.\n");
743 +
744 +               ret = -ENOENT;
745 +               goto probe_free_host;
746 +       }
747 +
748 +       host->mem = request_mem_region(host->mem->start,
749 +               RESSIZE(host->mem), pdev->name);
750 +
751 +       if (!host->mem) {
752 +               dev_err(&pdev->dev, "failed to request io memory region.\n");
753 +               ret = -ENOENT;
754 +               goto probe_free_host;
755 +       }
756 +
757 +       host->base = ioremap(host->mem->start, RESSIZE(host->mem));
758 +       if (!host->base) {
759 +               dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
760 +               ret = -EINVAL;
761 +               goto probe_free_mem_region;
762 +       }
763 +
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);
768 +
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");
774 +               ret = -ENOENT;
775 +               goto probe_iounmap;
776 +       }
777 +
778 +       host->mem_data = request_mem_region(host->mem_data->start,
779 +               RESSIZE(host->mem_data), pdev->name);
780 +
781 +       if (!host->mem_data) {
782 +               dev_err(&pdev->dev, "failed to request io memory region.\n");
783 +               ret = -ENOENT;
784 +               goto probe_iounmap;
785 +       }
786 +       host->base_data = ioremap(host->mem_data->start,
787 +                                         RESSIZE(host->mem_data));
788 +       host->data_max_size = RESSIZE(host->mem_data);
789 +
790 +       if (host->base_data == 0) {
791 +               dev_err(&pdev->dev, "failed to ioremap() io memory region.\n");
792 +               ret = -EINVAL;
793 +               goto probe_free_mem_region_data;
794 +       }
795 +
796 +       host->vdd_current = 0;
797 +       host->clk_rate = 50000000; /* really it's 49152000 */
798 +       host->clk_div = 16;
799 +
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;
808 +       /*
809 +        * held at /4 due to concerns of 100R recommended series resistor
810 +        * allows 16MHz @ 4-bit --> 8MBytes/sec raw
811 +        */
812 +       mmc->f_max      = host->clk_rate / 3;
813 +
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;
820 +
821 +       dev_info(&host->pdev->dev, "probe: mapped mci_base:%p irq:%u.\n",
822 +               host->base, host->irq);
823 +
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;
827 +       }
828 +
829 +       platform_set_drvdata(pdev, mmc);
830 +
831 +       dev_info(&pdev->dev,"initialisation done.\n");
832 +       return 0;
833 +
834 + probe_free_mem_region_data:
835 +       release_mem_region(host->mem_data->start, RESSIZE(host->mem_data));
836 +
837 + probe_iounmap:
838 +       iounmap(host->base);
839 +
840 + probe_free_mem_region:
841 +       release_mem_region(host->mem->start, RESSIZE(host->mem));
842 +
843 + probe_free_host:
844 +       mmc_free_host(mmc);
845 + probe_out:
846 +       return ret;
847 +}
848 +
849 +static int glamo_mci_remove(struct platform_device *pdev)
850 +{
851 +       struct mmc_host         *mmc  = platform_get_drvdata(pdev);
852 +       struct glamo_mci_host   *host = mmc_priv(mmc);
853 +
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);
862 +
863 +       glamo_engine_disable(glamo_mci_def_pdata.pglamo, GLAMO_ENGINE_MMC);
864 +       return 0;
865 +}
866 +
867 +
868 +#ifdef CONFIG_PM
869 +
870 +static int glamo_mci_suspend(struct platform_device *dev, pm_message_t state)
871 +{
872 +       struct mmc_host *mmc = platform_get_drvdata(dev);
873 +
874 +       return  mmc_suspend_host(mmc, state);
875 +}
876 +
877 +static int glamo_mci_resume(struct platform_device *dev)
878 +{
879 +       struct mmc_host *mmc = platform_get_drvdata(dev);
880 +
881 +       return mmc_resume_host(mmc);
882 +}
883 +
884 +#else /* CONFIG_PM */
885 +#define glamo_mci_suspend NULL
886 +#define glamo_mci_resume NULL
887 +#endif /* CONFIG_PM */
888 +
889 +
890 +static struct platform_driver glamo_mci_driver =
891 +{
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,
897 +};
898 +
899 +static int __init glamo_mci_init(void)
900 +{
901 +       platform_driver_register(&glamo_mci_driver);
902 +       return 0;
903 +}
904 +
905 +static void __exit glamo_mci_exit(void)
906 +{
907 +       platform_driver_unregister(&glamo_mci_driver);
908 +}
909 +
910 +module_init(glamo_mci_init);
911 +module_exit(glamo_mci_exit);
912 +
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
917 new file mode 100644
918 index 0000000..40c3e24
919 --- /dev/null
920 +++ b/drivers/mfd/glamo/glamo-mci.h
921 @@ -0,0 +1,76 @@
922 +/*
923 + *  linux/drivers/mmc/host/glamo-mmc.h - GLAMO MCI driver
924 + *
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.
928 + *
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.
932 + */
933 +
934 +
935 +enum glamo_mci_waitfor {
936 +       COMPLETION_NONE,
937 +       COMPLETION_FINALIZE,
938 +       COMPLETION_CMDSENT,
939 +       COMPLETION_RSPFIN,
940 +       COMPLETION_XFERFINISH,
941 +       COMPLETION_XFERFINISH_RSPFIN,
942 +};
943 +
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;
950 +       struct clk              *clk;
951 +       void __iomem            *base;
952 +       u16 __iomem             *base_data;
953 +       int                     irq;
954 +       int                     irq_cd;
955 +       int                     dma;
956 +       int                     data_max_size;
957 +
958 +       int                     power_mode_current;
959 +       unsigned int            vdd_current;
960 +
961 +       unsigned long           clk_rate;
962 +       unsigned long           clk_div;
963 +       unsigned long           real_rate;
964 +       u8                      prescaler;
965 +
966 +       unsigned                sdiimsk;
967 +       int                     dodma;
968 +
969 +       volatile int            dmatogo;
970 +
971 +       struct mmc_request      *mrq;
972 +       int                     cmd_is_stop;
973 +
974 +       spinlock_t              complete_lock;
975 +       volatile enum glamo_mci_waitfor
976 +                               complete_what;
977 +
978 +       volatile int            dma_complete;
979 +
980 +       volatile u32            pio_sgptr;
981 +       volatile u32            pio_words;
982 +       volatile u32            pio_count;
983 +       volatile u16            *pio_ptr;
984 +#define XFER_NONE 0
985 +#define XFER_READ 1
986 +#define XFER_WRITE 2
987 +       volatile u32            pio_active;
988 +
989 +       int                     bus_width;
990 +
991 +       char                    dbgmsg_cmd[301];
992 +       char                    dbgmsg_dat[301];
993 +       volatile char           *status;
994 +
995 +       unsigned int            ccnt, dcnt;
996 +       struct tasklet_struct   pio_tasklet;
997 +};
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),
1004  };
1005  
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,
1016 +};
1017 +
1018  enum glamo_irq {
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),
1037  };
1038  
1039  enum glamo_reg_clock_host {
1040 @@ -197,6 +209,145 @@ enum glamo_reg_clock_mmc {
1041         GLAMO_CLOCK_MMC_RESET           = 0x1000,
1042  };
1043  
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,
1070 +};
1071 +
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
1089 +};
1090 +
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
1095 +        */
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,
1103 +};
1104 +
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,
1112 +};
1113 +
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,
1123 +};
1124 +
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,
1148 +};
1149 +
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
1158 +        */
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,
1180 +
1181 +};
1182 +
1183  enum glamo_reg_clock_isp {
1184         GLAMO_CLOCK_ISP_DG_I1CLK        = 0x0001,
1185         GLAMO_CLOCK_ISP_EN_I1CLK        = 0x0002,
1186 -- 
1187 1.5.6.5
1188