OpenCores
URL https://opencores.org/ocsvn/test_project/test_project/trunk

Subversion Repositories test_project

[/] [test_project/] [trunk/] [linux_sd_driver/] [drivers/] [mmc/] [host/] [tifm_sd.c] - Blame information for rev 65

Go to most recent revision | Details | Compare with Previous | View Log

Line No. Rev Author Line
1 62 marcus.erl
/*
2
 *  tifm_sd.c - TI FlashMedia driver
3
 *
4
 *  Copyright (C) 2006 Alex Dubov <oakad@yahoo.com>
5
 *
6
 * This program is free software; you can redistribute it and/or modify
7
 * it under the terms of the GNU General Public License version 2 as
8
 * published by the Free Software Foundation.
9
 *
10
 * Special thanks to Brad Campbell for extensive testing of this driver.
11
 *
12
 */
13
 
14
 
15
#include <linux/tifm.h>
16
#include <linux/mmc/host.h>
17
#include <linux/highmem.h>
18
#include <linux/scatterlist.h>
19
#include <asm/io.h>
20
 
21
#define DRIVER_NAME "tifm_sd"
22
#define DRIVER_VERSION "0.8"
23
 
24
static int no_dma = 0;
25
static int fixed_timeout = 0;
26
module_param(no_dma, bool, 0644);
27
module_param(fixed_timeout, bool, 0644);
28
 
29
/* Constants here are mostly from OMAP5912 datasheet */
30
#define TIFM_MMCSD_RESET      0x0002
31
#define TIFM_MMCSD_CLKMASK    0x03ff
32
#define TIFM_MMCSD_POWER      0x0800
33
#define TIFM_MMCSD_4BBUS      0x8000
34
#define TIFM_MMCSD_RXDE       0x8000   /* rx dma enable */
35
#define TIFM_MMCSD_TXDE       0x0080   /* tx dma enable */
36
#define TIFM_MMCSD_BUFINT     0x0c00   /* set bits: AE, AF */
37
#define TIFM_MMCSD_DPE        0x0020   /* data timeout counted in kilocycles */
38
#define TIFM_MMCSD_INAB       0x0080   /* abort / initialize command */
39
#define TIFM_MMCSD_READ       0x8000
40
 
41
#define TIFM_MMCSD_ERRMASK    0x01e0   /* set bits: CCRC, CTO, DCRC, DTO */
42
#define TIFM_MMCSD_EOC        0x0001   /* end of command phase  */
43
#define TIFM_MMCSD_CD         0x0002   /* card detect           */
44
#define TIFM_MMCSD_CB         0x0004   /* card enter busy state */
45
#define TIFM_MMCSD_BRS        0x0008   /* block received/sent   */
46
#define TIFM_MMCSD_EOFB       0x0010   /* card exit busy state  */
47
#define TIFM_MMCSD_DTO        0x0020   /* data time-out         */
48
#define TIFM_MMCSD_DCRC       0x0040   /* data crc error        */
49
#define TIFM_MMCSD_CTO        0x0080   /* command time-out      */
50
#define TIFM_MMCSD_CCRC       0x0100   /* command crc error     */
51
#define TIFM_MMCSD_AF         0x0400   /* fifo almost full      */
52
#define TIFM_MMCSD_AE         0x0800   /* fifo almost empty     */
53
#define TIFM_MMCSD_OCRB       0x1000   /* OCR busy              */
54
#define TIFM_MMCSD_CIRQ       0x2000   /* card irq (cmd40/sdio) */
55
#define TIFM_MMCSD_CERR       0x4000   /* card status error     */
56
 
57
#define TIFM_MMCSD_ODTO       0x0040   /* open drain / extended timeout */
58
#define TIFM_MMCSD_CARD_RO    0x0200   /* card is read-only     */
59
 
60
#define TIFM_MMCSD_FIFO_SIZE  0x0020
61
 
62
#define TIFM_MMCSD_RSP_R0     0x0000
63
#define TIFM_MMCSD_RSP_R1     0x0100
64
#define TIFM_MMCSD_RSP_R2     0x0200
65
#define TIFM_MMCSD_RSP_R3     0x0300
66
#define TIFM_MMCSD_RSP_R4     0x0400
67
#define TIFM_MMCSD_RSP_R5     0x0500
68
#define TIFM_MMCSD_RSP_R6     0x0600
69
 
70
#define TIFM_MMCSD_RSP_BUSY   0x0800
71
 
72
#define TIFM_MMCSD_CMD_BC     0x0000
73
#define TIFM_MMCSD_CMD_BCR    0x1000
74
#define TIFM_MMCSD_CMD_AC     0x2000
75
#define TIFM_MMCSD_CMD_ADTC   0x3000
76
 
77
#define TIFM_MMCSD_MAX_BLOCK_SIZE  0x0800UL
78
 
79
enum {
80
        CMD_READY    = 0x0001,
81
        FIFO_READY   = 0x0002,
82
        BRS_READY    = 0x0004,
83
        SCMD_ACTIVE  = 0x0008,
84
        SCMD_READY   = 0x0010,
85
        CARD_BUSY    = 0x0020,
86
        DATA_CARRY   = 0x0040
87
};
88
 
89
struct tifm_sd {
90
        struct tifm_dev       *dev;
91
 
92
        unsigned short        eject:1,
93
                              open_drain:1,
94
                              no_dma:1;
95
        unsigned short        cmd_flags;
96
 
97
        unsigned int          clk_freq;
98
        unsigned int          clk_div;
99
        unsigned long         timeout_jiffies;
100
 
101
        struct tasklet_struct finish_tasklet;
102
        struct timer_list     timer;
103
        struct mmc_request    *req;
104
 
105
        int                   sg_len;
106
        int                   sg_pos;
107
        unsigned int          block_pos;
108
        struct scatterlist    bounce_buf;
109
        unsigned char         bounce_buf_data[TIFM_MMCSD_MAX_BLOCK_SIZE];
110
};
111
 
112
/* for some reason, host won't respond correctly to readw/writew */
113
static void tifm_sd_read_fifo(struct tifm_sd *host, struct page *pg,
114
                              unsigned int off, unsigned int cnt)
115
{
116
        struct tifm_dev *sock = host->dev;
117
        unsigned char *buf;
118
        unsigned int pos = 0, val;
119
 
120
        buf = kmap_atomic(pg, KM_BIO_DST_IRQ) + off;
121
        if (host->cmd_flags & DATA_CARRY) {
122
                buf[pos++] = host->bounce_buf_data[0];
123
                host->cmd_flags &= ~DATA_CARRY;
124
        }
125
 
126
        while (pos < cnt) {
127
                val = readl(sock->addr + SOCK_MMCSD_DATA);
128
                buf[pos++] = val & 0xff;
129
                if (pos == cnt) {
130
                        host->bounce_buf_data[0] = (val >> 8) & 0xff;
131
                        host->cmd_flags |= DATA_CARRY;
132
                        break;
133
                }
134
                buf[pos++] = (val >> 8) & 0xff;
135
        }
136
        kunmap_atomic(buf - off, KM_BIO_DST_IRQ);
137
}
138
 
139
static void tifm_sd_write_fifo(struct tifm_sd *host, struct page *pg,
140
                               unsigned int off, unsigned int cnt)
141
{
142
        struct tifm_dev *sock = host->dev;
143
        unsigned char *buf;
144
        unsigned int pos = 0, val;
145
 
146
        buf = kmap_atomic(pg, KM_BIO_SRC_IRQ) + off;
147
        if (host->cmd_flags & DATA_CARRY) {
148
                val = host->bounce_buf_data[0] | ((buf[pos++] << 8) & 0xff00);
149
                writel(val, sock->addr + SOCK_MMCSD_DATA);
150
                host->cmd_flags &= ~DATA_CARRY;
151
        }
152
 
153
        while (pos < cnt) {
154
                val = buf[pos++];
155
                if (pos == cnt) {
156
                        host->bounce_buf_data[0] = val & 0xff;
157
                        host->cmd_flags |= DATA_CARRY;
158
                        break;
159
                }
160
                val |= (buf[pos++] << 8) & 0xff00;
161
                writel(val, sock->addr + SOCK_MMCSD_DATA);
162
        }
163
        kunmap_atomic(buf - off, KM_BIO_SRC_IRQ);
164
}
165
 
166
static void tifm_sd_transfer_data(struct tifm_sd *host)
167
{
168
        struct mmc_data *r_data = host->req->cmd->data;
169
        struct scatterlist *sg = r_data->sg;
170
        unsigned int off, cnt, t_size = TIFM_MMCSD_FIFO_SIZE * 2;
171
        unsigned int p_off, p_cnt;
172
        struct page *pg;
173
 
174
        if (host->sg_pos == host->sg_len)
175
                return;
176
        while (t_size) {
177
                cnt = sg[host->sg_pos].length - host->block_pos;
178
                if (!cnt) {
179
                        host->block_pos = 0;
180
                        host->sg_pos++;
181
                        if (host->sg_pos == host->sg_len) {
182
                                if ((r_data->flags & MMC_DATA_WRITE)
183
                                    && DATA_CARRY)
184
                                        writel(host->bounce_buf_data[0],
185
                                               host->dev->addr
186
                                               + SOCK_MMCSD_DATA);
187
 
188
                                return;
189
                        }
190
                        cnt = sg[host->sg_pos].length;
191
                }
192
                off = sg[host->sg_pos].offset + host->block_pos;
193
 
194
                pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
195
                p_off = offset_in_page(off);
196
                p_cnt = PAGE_SIZE - p_off;
197
                p_cnt = min(p_cnt, cnt);
198
                p_cnt = min(p_cnt, t_size);
199
 
200
                if (r_data->flags & MMC_DATA_READ)
201
                        tifm_sd_read_fifo(host, pg, p_off, p_cnt);
202
                else if (r_data->flags & MMC_DATA_WRITE)
203
                        tifm_sd_write_fifo(host, pg, p_off, p_cnt);
204
 
205
                t_size -= p_cnt;
206
                host->block_pos += p_cnt;
207
        }
208
}
209
 
210
static void tifm_sd_copy_page(struct page *dst, unsigned int dst_off,
211
                              struct page *src, unsigned int src_off,
212
                              unsigned int count)
213
{
214
        unsigned char *src_buf = kmap_atomic(src, KM_BIO_SRC_IRQ) + src_off;
215
        unsigned char *dst_buf = kmap_atomic(dst, KM_BIO_DST_IRQ) + dst_off;
216
 
217
        memcpy(dst_buf, src_buf, count);
218
 
219
        kunmap_atomic(dst_buf - dst_off, KM_BIO_DST_IRQ);
220
        kunmap_atomic(src_buf - src_off, KM_BIO_SRC_IRQ);
221
}
222
 
223
static void tifm_sd_bounce_block(struct tifm_sd *host, struct mmc_data *r_data)
224
{
225
        struct scatterlist *sg = r_data->sg;
226
        unsigned int t_size = r_data->blksz;
227
        unsigned int off, cnt;
228
        unsigned int p_off, p_cnt;
229
        struct page *pg;
230
 
231
        dev_dbg(&host->dev->dev, "bouncing block\n");
232
        while (t_size) {
233
                cnt = sg[host->sg_pos].length - host->block_pos;
234
                if (!cnt) {
235
                        host->block_pos = 0;
236
                        host->sg_pos++;
237
                        if (host->sg_pos == host->sg_len)
238
                                return;
239
                        cnt = sg[host->sg_pos].length;
240
                }
241
                off = sg[host->sg_pos].offset + host->block_pos;
242
 
243
                pg = nth_page(sg_page(&sg[host->sg_pos]), off >> PAGE_SHIFT);
244
                p_off = offset_in_page(off);
245
                p_cnt = PAGE_SIZE - p_off;
246
                p_cnt = min(p_cnt, cnt);
247
                p_cnt = min(p_cnt, t_size);
248
 
249
                if (r_data->flags & MMC_DATA_WRITE)
250
                        tifm_sd_copy_page(sg_page(&host->bounce_buf),
251
                                          r_data->blksz - t_size,
252
                                          pg, p_off, p_cnt);
253
                else if (r_data->flags & MMC_DATA_READ)
254
                        tifm_sd_copy_page(pg, p_off, sg_page(&host->bounce_buf),
255
                                          r_data->blksz - t_size, p_cnt);
256
 
257
                t_size -= p_cnt;
258
                host->block_pos += p_cnt;
259
        }
260
}
261
 
262
static int tifm_sd_set_dma_data(struct tifm_sd *host, struct mmc_data *r_data)
263
{
264
        struct tifm_dev *sock = host->dev;
265
        unsigned int t_size = TIFM_DMA_TSIZE * r_data->blksz;
266
        unsigned int dma_len, dma_blk_cnt, dma_off;
267
        struct scatterlist *sg = NULL;
268
        unsigned long flags;
269
 
270
        if (host->sg_pos == host->sg_len)
271
                return 1;
272
 
273
        if (host->cmd_flags & DATA_CARRY) {
274
                host->cmd_flags &= ~DATA_CARRY;
275
                local_irq_save(flags);
276
                tifm_sd_bounce_block(host, r_data);
277
                local_irq_restore(flags);
278
                if (host->sg_pos == host->sg_len)
279
                        return 1;
280
        }
281
 
282
        dma_len = sg_dma_len(&r_data->sg[host->sg_pos]) - host->block_pos;
283
        if (!dma_len) {
284
                host->block_pos = 0;
285
                host->sg_pos++;
286
                if (host->sg_pos == host->sg_len)
287
                        return 1;
288
                dma_len = sg_dma_len(&r_data->sg[host->sg_pos]);
289
        }
290
 
291
        if (dma_len < t_size) {
292
                dma_blk_cnt = dma_len / r_data->blksz;
293
                dma_off = host->block_pos;
294
                host->block_pos += dma_blk_cnt * r_data->blksz;
295
        } else {
296
                dma_blk_cnt = TIFM_DMA_TSIZE;
297
                dma_off = host->block_pos;
298
                host->block_pos += t_size;
299
        }
300
 
301
        if (dma_blk_cnt)
302
                sg = &r_data->sg[host->sg_pos];
303
        else if (dma_len) {
304
                if (r_data->flags & MMC_DATA_WRITE) {
305
                        local_irq_save(flags);
306
                        tifm_sd_bounce_block(host, r_data);
307
                        local_irq_restore(flags);
308
                } else
309
                        host->cmd_flags |= DATA_CARRY;
310
 
311
                sg = &host->bounce_buf;
312
                dma_off = 0;
313
                dma_blk_cnt = 1;
314
        } else
315
                return 1;
316
 
317
        dev_dbg(&sock->dev, "setting dma for %d blocks\n", dma_blk_cnt);
318
        writel(sg_dma_address(sg) + dma_off, sock->addr + SOCK_DMA_ADDRESS);
319
        if (r_data->flags & MMC_DATA_WRITE)
320
                writel((dma_blk_cnt << 8) | TIFM_DMA_TX | TIFM_DMA_EN,
321
                       sock->addr + SOCK_DMA_CONTROL);
322
        else
323
                writel((dma_blk_cnt << 8) | TIFM_DMA_EN,
324
                       sock->addr + SOCK_DMA_CONTROL);
325
 
326
        return 0;
327
}
328
 
329
static unsigned int tifm_sd_op_flags(struct mmc_command *cmd)
330
{
331
        unsigned int rc = 0;
332
 
333
        switch (mmc_resp_type(cmd)) {
334
        case MMC_RSP_NONE:
335
                rc |= TIFM_MMCSD_RSP_R0;
336
                break;
337
        case MMC_RSP_R1B:
338
                rc |= TIFM_MMCSD_RSP_BUSY; // deliberate fall-through
339
        case MMC_RSP_R1:
340
                rc |= TIFM_MMCSD_RSP_R1;
341
                break;
342
        case MMC_RSP_R2:
343
                rc |= TIFM_MMCSD_RSP_R2;
344
                break;
345
        case MMC_RSP_R3:
346
                rc |= TIFM_MMCSD_RSP_R3;
347
                break;
348
        default:
349
                BUG();
350
        }
351
 
352
        switch (mmc_cmd_type(cmd)) {
353
        case MMC_CMD_BC:
354
                rc |= TIFM_MMCSD_CMD_BC;
355
                break;
356
        case MMC_CMD_BCR:
357
                rc |= TIFM_MMCSD_CMD_BCR;
358
                break;
359
        case MMC_CMD_AC:
360
                rc |= TIFM_MMCSD_CMD_AC;
361
                break;
362
        case MMC_CMD_ADTC:
363
                rc |= TIFM_MMCSD_CMD_ADTC;
364
                break;
365
        default:
366
                BUG();
367
        }
368
        return rc;
369
}
370
 
371
static void tifm_sd_exec(struct tifm_sd *host, struct mmc_command *cmd)
372
{
373
        struct tifm_dev *sock = host->dev;
374
        unsigned int cmd_mask = tifm_sd_op_flags(cmd);
375
 
376
        if (host->open_drain)
377
                cmd_mask |= TIFM_MMCSD_ODTO;
378
 
379
        if (cmd->data && (cmd->data->flags & MMC_DATA_READ))
380
                cmd_mask |= TIFM_MMCSD_READ;
381
 
382
        dev_dbg(&sock->dev, "executing opcode 0x%x, arg: 0x%x, mask: 0x%x\n",
383
                cmd->opcode, cmd->arg, cmd_mask);
384
 
385
        writel((cmd->arg >> 16) & 0xffff, sock->addr + SOCK_MMCSD_ARG_HIGH);
386
        writel(cmd->arg & 0xffff, sock->addr + SOCK_MMCSD_ARG_LOW);
387
        writel(cmd->opcode | cmd_mask, sock->addr + SOCK_MMCSD_COMMAND);
388
}
389
 
390
static void tifm_sd_fetch_resp(struct mmc_command *cmd, struct tifm_dev *sock)
391
{
392
        cmd->resp[0] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x1c) << 16)
393
                       | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x18);
394
        cmd->resp[1] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x14) << 16)
395
                       | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x10);
396
        cmd->resp[2] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x0c) << 16)
397
                       | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x08);
398
        cmd->resp[3] = (readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x04) << 16)
399
                       | readl(sock->addr + SOCK_MMCSD_RESPONSE + 0x00);
400
}
401
 
402
static void tifm_sd_check_status(struct tifm_sd *host)
403
{
404
        struct tifm_dev *sock = host->dev;
405
        struct mmc_command *cmd = host->req->cmd;
406
 
407
        if (cmd->error)
408
                goto finish_request;
409
 
410
        if (!(host->cmd_flags & CMD_READY))
411
                return;
412
 
413
        if (cmd->data) {
414
                if (cmd->data->error) {
415
                        if ((host->cmd_flags & SCMD_ACTIVE)
416
                            && !(host->cmd_flags & SCMD_READY))
417
                                return;
418
 
419
                        goto finish_request;
420
                }
421
 
422
                if (!(host->cmd_flags & BRS_READY))
423
                        return;
424
 
425
                if (!(host->no_dma || (host->cmd_flags & FIFO_READY)))
426
                        return;
427
 
428
                if (cmd->data->flags & MMC_DATA_WRITE) {
429
                        if (host->req->stop) {
430
                                if (!(host->cmd_flags & SCMD_ACTIVE)) {
431
                                        host->cmd_flags |= SCMD_ACTIVE;
432
                                        writel(TIFM_MMCSD_EOFB
433
                                               | readl(sock->addr
434
                                                       + SOCK_MMCSD_INT_ENABLE),
435
                                               sock->addr
436
                                               + SOCK_MMCSD_INT_ENABLE);
437
                                        tifm_sd_exec(host, host->req->stop);
438
                                        return;
439
                                } else {
440
                                        if (!(host->cmd_flags & SCMD_READY)
441
                                            || (host->cmd_flags & CARD_BUSY))
442
                                                return;
443
                                        writel((~TIFM_MMCSD_EOFB)
444
                                               & readl(sock->addr
445
                                                       + SOCK_MMCSD_INT_ENABLE),
446
                                               sock->addr
447
                                               + SOCK_MMCSD_INT_ENABLE);
448
                                }
449
                        } else {
450
                                if (host->cmd_flags & CARD_BUSY)
451
                                        return;
452
                                writel((~TIFM_MMCSD_EOFB)
453
                                       & readl(sock->addr
454
                                               + SOCK_MMCSD_INT_ENABLE),
455
                                       sock->addr + SOCK_MMCSD_INT_ENABLE);
456
                        }
457
                } else {
458
                        if (host->req->stop) {
459
                                if (!(host->cmd_flags & SCMD_ACTIVE)) {
460
                                        host->cmd_flags |= SCMD_ACTIVE;
461
                                        tifm_sd_exec(host, host->req->stop);
462
                                        return;
463
                                } else {
464
                                        if (!(host->cmd_flags & SCMD_READY))
465
                                                return;
466
                                }
467
                        }
468
                }
469
        }
470
finish_request:
471
        tasklet_schedule(&host->finish_tasklet);
472
}
473
 
474
/* Called from interrupt handler */
475
static void tifm_sd_data_event(struct tifm_dev *sock)
476
{
477
        struct tifm_sd *host;
478
        unsigned int fifo_status = 0;
479
        struct mmc_data *r_data = NULL;
480
 
481
        spin_lock(&sock->lock);
482
        host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock));
483
        fifo_status = readl(sock->addr + SOCK_DMA_FIFO_STATUS);
484
        dev_dbg(&sock->dev, "data event: fifo_status %x, flags %x\n",
485
                fifo_status, host->cmd_flags);
486
 
487
        if (host->req) {
488
                r_data = host->req->cmd->data;
489
 
490
                if (r_data && (fifo_status & TIFM_FIFO_READY)) {
491
                        if (tifm_sd_set_dma_data(host, r_data)) {
492
                                host->cmd_flags |= FIFO_READY;
493
                                tifm_sd_check_status(host);
494
                        }
495
                }
496
        }
497
 
498
        writel(fifo_status, sock->addr + SOCK_DMA_FIFO_STATUS);
499
        spin_unlock(&sock->lock);
500
}
501
 
502
/* Called from interrupt handler */
503
static void tifm_sd_card_event(struct tifm_dev *sock)
504
{
505
        struct tifm_sd *host;
506
        unsigned int host_status = 0;
507
        int cmd_error = 0;
508
        struct mmc_command *cmd = NULL;
509
        unsigned long flags;
510
 
511
        spin_lock(&sock->lock);
512
        host = mmc_priv((struct mmc_host*)tifm_get_drvdata(sock));
513
        host_status = readl(sock->addr + SOCK_MMCSD_STATUS);
514
        dev_dbg(&sock->dev, "host event: host_status %x, flags %x\n",
515
                host_status, host->cmd_flags);
516
 
517
        if (host->req) {
518
                cmd = host->req->cmd;
519
 
520
                if (host_status & TIFM_MMCSD_ERRMASK) {
521
                        writel(host_status & TIFM_MMCSD_ERRMASK,
522
                               sock->addr + SOCK_MMCSD_STATUS);
523
                        if (host_status & TIFM_MMCSD_CTO)
524
                                cmd_error = -ETIMEDOUT;
525
                        else if (host_status & TIFM_MMCSD_CCRC)
526
                                cmd_error = -EILSEQ;
527
 
528
                        if (cmd->data) {
529
                                if (host_status & TIFM_MMCSD_DTO)
530
                                        cmd->data->error = -ETIMEDOUT;
531
                                else if (host_status & TIFM_MMCSD_DCRC)
532
                                        cmd->data->error = -EILSEQ;
533
                        }
534
 
535
                        writel(TIFM_FIFO_INT_SETALL,
536
                               sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
537
                        writel(TIFM_DMA_RESET, sock->addr + SOCK_DMA_CONTROL);
538
 
539
                        if (host->req->stop) {
540
                                if (host->cmd_flags & SCMD_ACTIVE) {
541
                                        host->req->stop->error = cmd_error;
542
                                        host->cmd_flags |= SCMD_READY;
543
                                } else {
544
                                        cmd->error = cmd_error;
545
                                        host->cmd_flags |= SCMD_ACTIVE;
546
                                        tifm_sd_exec(host, host->req->stop);
547
                                        goto done;
548
                                }
549
                        } else
550
                                cmd->error = cmd_error;
551
                } else {
552
                        if (host_status & (TIFM_MMCSD_EOC | TIFM_MMCSD_CERR)) {
553
                                if (!(host->cmd_flags & CMD_READY)) {
554
                                        host->cmd_flags |= CMD_READY;
555
                                        tifm_sd_fetch_resp(cmd, sock);
556
                                } else if (host->cmd_flags & SCMD_ACTIVE) {
557
                                        host->cmd_flags |= SCMD_READY;
558
                                        tifm_sd_fetch_resp(host->req->stop,
559
                                                           sock);
560
                                }
561
                        }
562
                        if (host_status & TIFM_MMCSD_BRS)
563
                                host->cmd_flags |= BRS_READY;
564
                }
565
 
566
                if (host->no_dma && cmd->data) {
567
                        if (host_status & TIFM_MMCSD_AE)
568
                                writel(host_status & TIFM_MMCSD_AE,
569
                                       sock->addr + SOCK_MMCSD_STATUS);
570
 
571
                        if (host_status & (TIFM_MMCSD_AE | TIFM_MMCSD_AF
572
                                           | TIFM_MMCSD_BRS)) {
573
                                local_irq_save(flags);
574
                                tifm_sd_transfer_data(host);
575
                                local_irq_restore(flags);
576
                                host_status &= ~TIFM_MMCSD_AE;
577
                        }
578
                }
579
 
580
                if (host_status & TIFM_MMCSD_EOFB)
581
                        host->cmd_flags &= ~CARD_BUSY;
582
                else if (host_status & TIFM_MMCSD_CB)
583
                        host->cmd_flags |= CARD_BUSY;
584
 
585
                tifm_sd_check_status(host);
586
        }
587
done:
588
        writel(host_status, sock->addr + SOCK_MMCSD_STATUS);
589
        spin_unlock(&sock->lock);
590
}
591
 
592
static void tifm_sd_set_data_timeout(struct tifm_sd *host,
593
                                     struct mmc_data *data)
594
{
595
        struct tifm_dev *sock = host->dev;
596
        unsigned int data_timeout = data->timeout_clks;
597
 
598
        if (fixed_timeout)
599
                return;
600
 
601
        data_timeout += data->timeout_ns /
602
                        ((1000000000UL / host->clk_freq) * host->clk_div);
603
 
604
        if (data_timeout < 0xffff) {
605
                writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO);
606
                writel((~TIFM_MMCSD_DPE)
607
                       & readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
608
                       sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
609
        } else {
610
                data_timeout = (data_timeout >> 10) + 1;
611
                if (data_timeout > 0xffff)
612
                        data_timeout = 0;        /* set to unlimited */
613
                writel(data_timeout, sock->addr + SOCK_MMCSD_DATA_TO);
614
                writel(TIFM_MMCSD_DPE
615
                       | readl(sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG),
616
                       sock->addr + SOCK_MMCSD_SDIO_MODE_CONFIG);
617
        }
618
}
619
 
620
static void tifm_sd_request(struct mmc_host *mmc, struct mmc_request *mrq)
621
{
622
        struct tifm_sd *host = mmc_priv(mmc);
623
        struct tifm_dev *sock = host->dev;
624
        unsigned long flags;
625
        struct mmc_data *r_data = mrq->cmd->data;
626
 
627
        spin_lock_irqsave(&sock->lock, flags);
628
        if (host->eject) {
629
                mrq->cmd->error = -ENOMEDIUM;
630
                goto err_out;
631
        }
632
 
633
        if (host->req) {
634
                printk(KERN_ERR "%s : unfinished request detected\n",
635
                       sock->dev.bus_id);
636
                mrq->cmd->error = -ETIMEDOUT;
637
                goto err_out;
638
        }
639
 
640
        host->cmd_flags = 0;
641
        host->block_pos = 0;
642
        host->sg_pos = 0;
643
 
644
        if (mrq->data && !is_power_of_2(mrq->data->blksz))
645
                host->no_dma = 1;
646
        else
647
                host->no_dma = no_dma ? 1 : 0;
648
 
649
        if (r_data) {
650
                tifm_sd_set_data_timeout(host, r_data);
651
 
652
                if ((r_data->flags & MMC_DATA_WRITE) && !mrq->stop)
653
                         writel(TIFM_MMCSD_EOFB
654
                                | readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
655
                                sock->addr + SOCK_MMCSD_INT_ENABLE);
656
 
657
                if (host->no_dma) {
658
                        writel(TIFM_MMCSD_BUFINT
659
                               | readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
660
                               sock->addr + SOCK_MMCSD_INT_ENABLE);
661
                        writel(((TIFM_MMCSD_FIFO_SIZE - 1) << 8)
662
                               | (TIFM_MMCSD_FIFO_SIZE - 1),
663
                               sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
664
 
665
                        host->sg_len = r_data->sg_len;
666
                } else {
667
                        sg_init_one(&host->bounce_buf, host->bounce_buf_data,
668
                                    r_data->blksz);
669
 
670
                        if(1 != tifm_map_sg(sock, &host->bounce_buf, 1,
671
                                            r_data->flags & MMC_DATA_WRITE
672
                                            ? PCI_DMA_TODEVICE
673
                                            : PCI_DMA_FROMDEVICE)) {
674
                                printk(KERN_ERR "%s : scatterlist map failed\n",
675
                                       sock->dev.bus_id);
676
                                mrq->cmd->error = -ENOMEM;
677
                                goto err_out;
678
                        }
679
                        host->sg_len = tifm_map_sg(sock, r_data->sg,
680
                                                   r_data->sg_len,
681
                                                   r_data->flags
682
                                                   & MMC_DATA_WRITE
683
                                                   ? PCI_DMA_TODEVICE
684
                                                   : PCI_DMA_FROMDEVICE);
685
                        if (host->sg_len < 1) {
686
                                printk(KERN_ERR "%s : scatterlist map failed\n",
687
                                       sock->dev.bus_id);
688
                                tifm_unmap_sg(sock, &host->bounce_buf, 1,
689
                                              r_data->flags & MMC_DATA_WRITE
690
                                              ? PCI_DMA_TODEVICE
691
                                              : PCI_DMA_FROMDEVICE);
692
                                mrq->cmd->error = -ENOMEM;
693
                                goto err_out;
694
                        }
695
 
696
                        writel(TIFM_FIFO_INT_SETALL,
697
                               sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
698
                        writel(ilog2(r_data->blksz) - 2,
699
                               sock->addr + SOCK_FIFO_PAGE_SIZE);
700
                        writel(TIFM_FIFO_ENABLE,
701
                               sock->addr + SOCK_FIFO_CONTROL);
702
                        writel(TIFM_FIFO_INTMASK,
703
                               sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
704
 
705
                        if (r_data->flags & MMC_DATA_WRITE)
706
                                writel(TIFM_MMCSD_TXDE,
707
                                       sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
708
                        else
709
                                writel(TIFM_MMCSD_RXDE,
710
                                       sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
711
 
712
                        tifm_sd_set_dma_data(host, r_data);
713
                }
714
 
715
                writel(r_data->blocks - 1,
716
                       sock->addr + SOCK_MMCSD_NUM_BLOCKS);
717
                writel(r_data->blksz - 1,
718
                       sock->addr + SOCK_MMCSD_BLOCK_LEN);
719
        }
720
 
721
        host->req = mrq;
722
        mod_timer(&host->timer, jiffies + host->timeout_jiffies);
723
        writel(TIFM_CTRL_LED | readl(sock->addr + SOCK_CONTROL),
724
               sock->addr + SOCK_CONTROL);
725
        tifm_sd_exec(host, mrq->cmd);
726
        spin_unlock_irqrestore(&sock->lock, flags);
727
        return;
728
 
729
err_out:
730
        spin_unlock_irqrestore(&sock->lock, flags);
731
        mmc_request_done(mmc, mrq);
732
}
733
 
734
static void tifm_sd_end_cmd(unsigned long data)
735
{
736
        struct tifm_sd *host = (struct tifm_sd*)data;
737
        struct tifm_dev *sock = host->dev;
738
        struct mmc_host *mmc = tifm_get_drvdata(sock);
739
        struct mmc_request *mrq;
740
        struct mmc_data *r_data = NULL;
741
        unsigned long flags;
742
 
743
        spin_lock_irqsave(&sock->lock, flags);
744
 
745
        del_timer(&host->timer);
746
        mrq = host->req;
747
        host->req = NULL;
748
 
749
        if (!mrq) {
750
                printk(KERN_ERR " %s : no request to complete?\n",
751
                       sock->dev.bus_id);
752
                spin_unlock_irqrestore(&sock->lock, flags);
753
                return;
754
        }
755
 
756
        r_data = mrq->cmd->data;
757
        if (r_data) {
758
                if (host->no_dma) {
759
                        writel((~TIFM_MMCSD_BUFINT)
760
                               & readl(sock->addr + SOCK_MMCSD_INT_ENABLE),
761
                               sock->addr + SOCK_MMCSD_INT_ENABLE);
762
                } else {
763
                        tifm_unmap_sg(sock, &host->bounce_buf, 1,
764
                                      (r_data->flags & MMC_DATA_WRITE)
765
                                      ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
766
                        tifm_unmap_sg(sock, r_data->sg, r_data->sg_len,
767
                                      (r_data->flags & MMC_DATA_WRITE)
768
                                      ? PCI_DMA_TODEVICE : PCI_DMA_FROMDEVICE);
769
                }
770
 
771
                r_data->bytes_xfered = r_data->blocks
772
                        - readl(sock->addr + SOCK_MMCSD_NUM_BLOCKS) - 1;
773
                r_data->bytes_xfered *= r_data->blksz;
774
                r_data->bytes_xfered += r_data->blksz
775
                        - readl(sock->addr + SOCK_MMCSD_BLOCK_LEN) + 1;
776
        }
777
 
778
        writel((~TIFM_CTRL_LED) & readl(sock->addr + SOCK_CONTROL),
779
               sock->addr + SOCK_CONTROL);
780
 
781
        spin_unlock_irqrestore(&sock->lock, flags);
782
        mmc_request_done(mmc, mrq);
783
}
784
 
785
static void tifm_sd_abort(unsigned long data)
786
{
787
        struct tifm_sd *host = (struct tifm_sd*)data;
788
 
789
        printk(KERN_ERR
790
               "%s : card failed to respond for a long period of time "
791
               "(%x, %x)\n",
792
               host->dev->dev.bus_id, host->req->cmd->opcode, host->cmd_flags);
793
 
794
        tifm_eject(host->dev);
795
}
796
 
797
static void tifm_sd_ios(struct mmc_host *mmc, struct mmc_ios *ios)
798
{
799
        struct tifm_sd *host = mmc_priv(mmc);
800
        struct tifm_dev *sock = host->dev;
801
        unsigned int clk_div1, clk_div2;
802
        unsigned long flags;
803
 
804
        spin_lock_irqsave(&sock->lock, flags);
805
 
806
        dev_dbg(&sock->dev, "ios: clock = %u, vdd = %x, bus_mode = %x, "
807
                "chip_select = %x, power_mode = %x, bus_width = %x\n",
808
                ios->clock, ios->vdd, ios->bus_mode, ios->chip_select,
809
                ios->power_mode, ios->bus_width);
810
 
811
        if (ios->bus_width == MMC_BUS_WIDTH_4) {
812
                writel(TIFM_MMCSD_4BBUS | readl(sock->addr + SOCK_MMCSD_CONFIG),
813
                       sock->addr + SOCK_MMCSD_CONFIG);
814
        } else {
815
                writel((~TIFM_MMCSD_4BBUS)
816
                       & readl(sock->addr + SOCK_MMCSD_CONFIG),
817
                       sock->addr + SOCK_MMCSD_CONFIG);
818
        }
819
 
820
        if (ios->clock) {
821
                clk_div1 = 20000000 / ios->clock;
822
                if (!clk_div1)
823
                        clk_div1 = 1;
824
 
825
                clk_div2 = 24000000 / ios->clock;
826
                if (!clk_div2)
827
                        clk_div2 = 1;
828
 
829
                if ((20000000 / clk_div1) > ios->clock)
830
                        clk_div1++;
831
                if ((24000000 / clk_div2) > ios->clock)
832
                        clk_div2++;
833
                if ((20000000 / clk_div1) > (24000000 / clk_div2)) {
834
                        host->clk_freq = 20000000;
835
                        host->clk_div = clk_div1;
836
                        writel((~TIFM_CTRL_FAST_CLK)
837
                               & readl(sock->addr + SOCK_CONTROL),
838
                               sock->addr + SOCK_CONTROL);
839
                } else {
840
                        host->clk_freq = 24000000;
841
                        host->clk_div = clk_div2;
842
                        writel(TIFM_CTRL_FAST_CLK
843
                               | readl(sock->addr + SOCK_CONTROL),
844
                               sock->addr + SOCK_CONTROL);
845
                }
846
        } else {
847
                host->clk_div = 0;
848
        }
849
        host->clk_div &= TIFM_MMCSD_CLKMASK;
850
        writel(host->clk_div
851
               | ((~TIFM_MMCSD_CLKMASK)
852
                  & readl(sock->addr + SOCK_MMCSD_CONFIG)),
853
               sock->addr + SOCK_MMCSD_CONFIG);
854
 
855
        host->open_drain = (ios->bus_mode == MMC_BUSMODE_OPENDRAIN);
856
 
857
        /* chip_select : maybe later */
858
        //vdd
859
        //power is set before probe / after remove
860
 
861
        spin_unlock_irqrestore(&sock->lock, flags);
862
}
863
 
864
static int tifm_sd_ro(struct mmc_host *mmc)
865
{
866
        int rc = 0;
867
        struct tifm_sd *host = mmc_priv(mmc);
868
        struct tifm_dev *sock = host->dev;
869
        unsigned long flags;
870
 
871
        spin_lock_irqsave(&sock->lock, flags);
872
        if (TIFM_MMCSD_CARD_RO & readl(sock->addr + SOCK_PRESENT_STATE))
873
                rc = 1;
874
        spin_unlock_irqrestore(&sock->lock, flags);
875
        return rc;
876
}
877
 
878
static const struct mmc_host_ops tifm_sd_ops = {
879
        .request = tifm_sd_request,
880
        .set_ios = tifm_sd_ios,
881
        .get_ro  = tifm_sd_ro
882
};
883
 
884
static int tifm_sd_initialize_host(struct tifm_sd *host)
885
{
886
        int rc;
887
        unsigned int host_status = 0;
888
        struct tifm_dev *sock = host->dev;
889
 
890
        writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
891
        mmiowb();
892
        host->clk_div = 61;
893
        host->clk_freq = 20000000;
894
        writel(TIFM_MMCSD_RESET, sock->addr + SOCK_MMCSD_SYSTEM_CONTROL);
895
        writel(host->clk_div | TIFM_MMCSD_POWER,
896
               sock->addr + SOCK_MMCSD_CONFIG);
897
 
898
        /* wait up to 0.51 sec for reset */
899
        for (rc = 32; rc <= 256; rc <<= 1) {
900
                if (1 & readl(sock->addr + SOCK_MMCSD_SYSTEM_STATUS)) {
901
                        rc = 0;
902
                        break;
903
                }
904
                msleep(rc);
905
        }
906
 
907
        if (rc) {
908
                printk(KERN_ERR "%s : controller failed to reset\n",
909
                       sock->dev.bus_id);
910
                return -ENODEV;
911
        }
912
 
913
        writel(0, sock->addr + SOCK_MMCSD_NUM_BLOCKS);
914
        writel(host->clk_div | TIFM_MMCSD_POWER,
915
               sock->addr + SOCK_MMCSD_CONFIG);
916
        writel(TIFM_MMCSD_RXDE, sock->addr + SOCK_MMCSD_BUFFER_CONFIG);
917
 
918
        // command timeout fixed to 64 clocks for now
919
        writel(64, sock->addr + SOCK_MMCSD_COMMAND_TO);
920
        writel(TIFM_MMCSD_INAB, sock->addr + SOCK_MMCSD_COMMAND);
921
 
922
        for (rc = 16; rc <= 64; rc <<= 1) {
923
                host_status = readl(sock->addr + SOCK_MMCSD_STATUS);
924
                writel(host_status, sock->addr + SOCK_MMCSD_STATUS);
925
                if (!(host_status & TIFM_MMCSD_ERRMASK)
926
                    && (host_status & TIFM_MMCSD_EOC)) {
927
                        rc = 0;
928
                        break;
929
                }
930
                msleep(rc);
931
        }
932
 
933
        if (rc) {
934
                printk(KERN_ERR
935
                       "%s : card not ready - probe failed on initialization\n",
936
                       sock->dev.bus_id);
937
                return -ENODEV;
938
        }
939
 
940
        writel(TIFM_MMCSD_CERR | TIFM_MMCSD_BRS | TIFM_MMCSD_EOC
941
               | TIFM_MMCSD_ERRMASK,
942
               sock->addr + SOCK_MMCSD_INT_ENABLE);
943
        mmiowb();
944
 
945
        return 0;
946
}
947
 
948
static int tifm_sd_probe(struct tifm_dev *sock)
949
{
950
        struct mmc_host *mmc;
951
        struct tifm_sd *host;
952
        int rc = -EIO;
953
 
954
        if (!(TIFM_SOCK_STATE_OCCUPIED
955
              & readl(sock->addr + SOCK_PRESENT_STATE))) {
956
                printk(KERN_WARNING "%s : card gone, unexpectedly\n",
957
                       sock->dev.bus_id);
958
                return rc;
959
        }
960
 
961
        mmc = mmc_alloc_host(sizeof(struct tifm_sd), &sock->dev);
962
        if (!mmc)
963
                return -ENOMEM;
964
 
965
        host = mmc_priv(mmc);
966
        tifm_set_drvdata(sock, mmc);
967
        host->dev = sock;
968
        host->timeout_jiffies = msecs_to_jiffies(1000);
969
 
970
        tasklet_init(&host->finish_tasklet, tifm_sd_end_cmd,
971
                     (unsigned long)host);
972
        setup_timer(&host->timer, tifm_sd_abort, (unsigned long)host);
973
 
974
        mmc->ops = &tifm_sd_ops;
975
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
976
        mmc->caps = MMC_CAP_4_BIT_DATA | MMC_CAP_MULTIWRITE;
977
        mmc->f_min = 20000000 / 60;
978
        mmc->f_max = 24000000;
979
 
980
        mmc->max_blk_count = 2048;
981
        mmc->max_hw_segs = mmc->max_blk_count;
982
        mmc->max_blk_size = min(TIFM_MMCSD_MAX_BLOCK_SIZE, PAGE_SIZE);
983
        mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size;
984
        mmc->max_req_size = mmc->max_seg_size;
985
        mmc->max_phys_segs = mmc->max_hw_segs;
986
 
987
        sock->card_event = tifm_sd_card_event;
988
        sock->data_event = tifm_sd_data_event;
989
        rc = tifm_sd_initialize_host(host);
990
 
991
        if (!rc)
992
                rc = mmc_add_host(mmc);
993
        if (!rc)
994
                return 0;
995
 
996
        mmc_free_host(mmc);
997
        return rc;
998
}
999
 
1000
static void tifm_sd_remove(struct tifm_dev *sock)
1001
{
1002
        struct mmc_host *mmc = tifm_get_drvdata(sock);
1003
        struct tifm_sd *host = mmc_priv(mmc);
1004
        unsigned long flags;
1005
 
1006
        spin_lock_irqsave(&sock->lock, flags);
1007
        host->eject = 1;
1008
        writel(0, sock->addr + SOCK_MMCSD_INT_ENABLE);
1009
        mmiowb();
1010
        spin_unlock_irqrestore(&sock->lock, flags);
1011
 
1012
        tasklet_kill(&host->finish_tasklet);
1013
 
1014
        spin_lock_irqsave(&sock->lock, flags);
1015
        if (host->req) {
1016
                writel(TIFM_FIFO_INT_SETALL,
1017
                       sock->addr + SOCK_DMA_FIFO_INT_ENABLE_CLEAR);
1018
                writel(0, sock->addr + SOCK_DMA_FIFO_INT_ENABLE_SET);
1019
                host->req->cmd->error = -ENOMEDIUM;
1020
                if (host->req->stop)
1021
                        host->req->stop->error = -ENOMEDIUM;
1022
                tasklet_schedule(&host->finish_tasklet);
1023
        }
1024
        spin_unlock_irqrestore(&sock->lock, flags);
1025
        mmc_remove_host(mmc);
1026
        dev_dbg(&sock->dev, "after remove\n");
1027
 
1028
        mmc_free_host(mmc);
1029
}
1030
 
1031
#ifdef CONFIG_PM
1032
 
1033
static int tifm_sd_suspend(struct tifm_dev *sock, pm_message_t state)
1034
{
1035
        return mmc_suspend_host(tifm_get_drvdata(sock), state);
1036
}
1037
 
1038
static int tifm_sd_resume(struct tifm_dev *sock)
1039
{
1040
        struct mmc_host *mmc = tifm_get_drvdata(sock);
1041
        struct tifm_sd *host = mmc_priv(mmc);
1042
        int rc;
1043
 
1044
        rc = tifm_sd_initialize_host(host);
1045
        dev_dbg(&sock->dev, "resume initialize %d\n", rc);
1046
 
1047
        if (rc)
1048
                host->eject = 1;
1049
        else
1050
                rc = mmc_resume_host(mmc);
1051
 
1052
        return rc;
1053
}
1054
 
1055
#else
1056
 
1057
#define tifm_sd_suspend NULL
1058
#define tifm_sd_resume NULL
1059
 
1060
#endif /* CONFIG_PM */
1061
 
1062
static struct tifm_device_id tifm_sd_id_tbl[] = {
1063
        { TIFM_TYPE_SD }, { }
1064
};
1065
 
1066
static struct tifm_driver tifm_sd_driver = {
1067
        .driver = {
1068
                .name  = DRIVER_NAME,
1069
                .owner = THIS_MODULE
1070
        },
1071
        .id_table = tifm_sd_id_tbl,
1072
        .probe    = tifm_sd_probe,
1073
        .remove   = tifm_sd_remove,
1074
        .suspend  = tifm_sd_suspend,
1075
        .resume   = tifm_sd_resume
1076
};
1077
 
1078
static int __init tifm_sd_init(void)
1079
{
1080
        return tifm_register_driver(&tifm_sd_driver);
1081
}
1082
 
1083
static void __exit tifm_sd_exit(void)
1084
{
1085
        tifm_unregister_driver(&tifm_sd_driver);
1086
}
1087
 
1088
MODULE_AUTHOR("Alex Dubov");
1089
MODULE_DESCRIPTION("TI FlashMedia SD driver");
1090
MODULE_LICENSE("GPL");
1091
MODULE_DEVICE_TABLE(tifm, tifm_sd_id_tbl);
1092
MODULE_VERSION(DRIVER_VERSION);
1093
 
1094
module_init(tifm_sd_init);
1095
module_exit(tifm_sd_exit);

powered by: WebSVN 2.1.0

© copyright 1999-2025 OpenCores.org, equivalent to Oliscience, all rights reserved. OpenCores®, registered trademark.