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

Subversion Repositories test_project

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

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

Line No. Rev Author Line
1 65 AlbertVeli
/* -*- linux-c -*-
2
 *
3
 * OpenCores MMC Controller driver
4
 *
5 81 tac2
 *
6
 * Command 51 and Command 2 hardcoded
7
 *
8
 *
9
 *
10 65 AlbertVeli
 * Copyright (C) 2009 ORSoC, All Rights Reserved.
11
 *
12
 * This program is free software; you can redistribute it and/or modify it
13
 * under the terms of the GNU General Public License as published
14
 * by the Free Software Foundation; version 2 of the License.
15
 *
16
 * This program is distributed in the hope that it will be useful, but
17
 * WITHOUT ANY WARRANTY; without even the implied warranty of
18
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
19
 * General Public License for more details.
20
 *
21
 * You should have received a copy of the GNU General Public License along
22
 * with this program; if not, write to the Free Software Foundation, Inc.,
23
 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
24
 */
25
#include <linux/module.h>
26
#include <linux/init.h>
27
#include <linux/ioport.h>
28
#include <linux/platform_device.h>
29
#include <linux/delay.h>
30
#include <linux/interrupt.h>
31
#include <linux/err.h>
32
#include <linux/mmc/host.h>
33 81 tac2
#include <linux/dma-mapping.h>
34
#include <linux/scatterlist.h>
35
#include <linux/highmem.h>
36 65 AlbertVeli
#include <asm/board.h>
37
#include <asm/io.h>
38 81 tac2
#include <asm/irq.h>
39 65 AlbertVeli
#include <asm/mmc.h>
40 68 tac2
#include <asm/system.h>
41 81 tac2
#include <linux/mmc/card.h>
42 65 AlbertVeli
#include "mmc_ocores.h"
43
 
44
#define DRIVER_NAME "mmc-ocores"
45
 
46
#define NR_SG   1
47
 
48 66 tac2
 
49 70 tac2
 
50 81 tac2
 
51 65 AlbertVeli
struct ocores_host {
52
        struct mmc_host         *mmc;
53
        spinlock_t              lock;
54
        struct resource         *res;
55
        void __iomem            *base;
56
        unsigned int            cmdat;
57
        unsigned int            power_mode;
58
        struct ocores_platform_data *pdata;
59 69 AlbertVeli
        unsigned int            word_cnt;
60 65 AlbertVeli
        struct mmc_request      *mrq;
61
        struct mmc_command      *cmd;
62
        struct mmc_data         *data;
63 66 tac2
        int irq_cmd;
64
        int irq_dat;
65
        unsigned int flags;
66
        struct tasklet_struct finish_cmd;
67 81 tac2
        struct tasklet_struct finish_data;
68 68 tac2
        struct {
69 69 AlbertVeli
                unsigned int normal_int_status;
70
                unsigned int error_int_status;
71 81 tac2
                unsigned int data_int_status;
72 69 AlbertVeli
        } registers;
73 76 tac2
        int clock;
74 81 tac2
 
75
        /* DMA buffer used for transmitting */
76
        unsigned int* buffer;
77
        dma_addr_t physical_address;
78
        unsigned int total_length;
79
        unsigned int            dma_len;
80
        /* Latest in the scatterlist that has been enabled for transfer, but not freed */
81
        int in_use_index;
82
 
83
        /* Latest in the scatterlist that has been enabled for transfer */
84
        int transfer_index;
85
        int free_tx_bd;
86
        int free_rx_bd;
87 65 AlbertVeli
};
88
 
89 66 tac2
struct ocores_host *oc_host;
90
 
91
static void ocores_tasklet_finish_cmd(unsigned long param);
92 81 tac2
static void ocores_tasklet_finish_data(unsigned long param);
93
 
94 66 tac2
static inline void CMD_IRQ_ON(struct ocores_host *host, u32 mask)
95 65 AlbertVeli
{
96 81 tac2
        u32 val = readl(host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
97 66 tac2
        val |= mask;
98 81 tac2
        writel (val, host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
99 66 tac2
}
100
 
101
static inline void CMD_IRQ_OFF(struct ocores_host *host, u32 mask)
102 69 AlbertVeli
{
103 66 tac2
        u32 val = readl(host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
104
        val  &= ~mask;
105
        writel (val, host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
106
}
107 69 AlbertVeli
 
108 81 tac2
static inline void DAT_IRQ_ON(struct ocores_host *host, u32 mask)
109
{
110
        u32 val = readl(host->base  + SD_BD_ISER);
111
        val |= mask;
112
        writel (val, host->base  + SD_BD_ISER);
113
}
114
 
115
static inline void DAT_IRQ_OFF(struct ocores_host *host, u32 mask)
116
{
117
        u32 val = readl(host->base  + SD_BD_ISER);
118
        val  &= ~mask;
119
        writel (val, host->base  + SD_BD_ISER);
120
}
121
 
122
 
123
static void ocores_pre_dma_read(struct ocores_host *host)
124
{
125
        int i,j;
126
        int off_scal;
127
        struct scatterlist *sg;
128
        struct mmc_command *cmd;
129
        struct mmc_data *data;
130
 
131
        off_scal=512;
132
        if (host->mmc->card!= NULL){
133
 
134
                if (mmc_card_blockaddr(host->mmc->card))
135
                        off_scal=1;
136
                else
137
                        off_scal=512;
138
        }
139
        printk("pre dma read off %d\n", off_scal);
140
 
141
        cmd = host->cmd;
142
        if (!cmd) {
143
                pr_debug("no command\n");
144
                return;
145
        }
146
        data = cmd->data;
147
        if (!data) {
148
                pr_debug("no data\n");
149
                return;
150
        }
151
 
152
        /* Setup the next transfer */
153
        pr_debug("Using transfer index %d\n", host->transfer_index);
154
 
155
        sg = &data->sg[host->transfer_index++];
156
        printk("Using transfer index %d, sg offset %d\n", host->transfer_index,sg->offset);
157
        pr_debug("sg = %p\n", sg);
158
        printk("sg = %p\n", sg);
159
 
160
 
161
        host->dma_len = dma_map_sg(mmc_dev(host->mmc), sg, data->sg_len,  DMA_FROM_DEVICE);
162
        printk(KERN_ALERT "dma address = %d, sg_dma_len %d, length = %d, sg_dma_len %d\n", sg_dma_address(&data->sg[0]),  sg_dma_len(&data->sg[0]), sg->length, host->dma_len);
163
        for (i = 0; i < host->dma_len; i++) {
164
                unsigned int length = sg_dma_len(&data->sg[i]);
165
 
166
                if (length >= 512)
167
                        length /=512;
168
                else
169
                        length = 1;
170
 
171
                printk(KERN_ALERT "DMA LEN %d\n", length);
172
                //XXX:512 SD 1.0 card only.
173
                for (j = 0; j< length;j++) {
174
                        pr_debug("dma address = %d, length = %d\n", sg_dma_address(&data->sg[i]), sg->length);
175
                        printk(KERN_ALERT "dma address = %d, length = %d, sg_dma_len %d\n", (sg_dma_address(&data->sg[i])+512*j), length, host->dma_len);
176
 
177
                        writel((sg_dma_address(&data->sg[i])+512*j), host->base + BD_RX);
178
                        wmb();
179
                        writel(cmd->arg+off_scal*j, host->base + BD_RX);
180
 
181
                }
182
 
183
        }
184
 
185
        DAT_IRQ_ON (host,(TRE|FIFOE|MRC|TRS));
186
        pr_debug("pre dma read done\n");
187
}
188
static void ocores_pre_dma_write(struct ocores_host *host)
189
{
190
        int i,j;
191
        int off_scal;
192
        struct scatterlist *sg;
193
        struct mmc_command *cmd;
194
        struct mmc_data *data;
195
 
196
        off_scal=512;
197
        if (host->mmc->card!= NULL){
198
 
199
                if (mmc_card_blockaddr(host->mmc->card))
200
                        off_scal=1;
201
                else
202
                        off_scal=512;
203
        }
204
        printk("pre dma write off %d\n", off_scal);
205
 
206
        cmd = host->cmd;
207
        if (!cmd) {
208
                pr_debug("no command\n");
209
                return;
210
        }
211
        data = cmd->data;
212
        if (!data) {
213
                pr_debug("no data\n");
214
                return;
215
        }
216
 
217
        /* Setup the next transfer */
218
        pr_debug("Using transfer index %d\n", host->transfer_index);
219
 
220
        sg = &data->sg[host->transfer_index++];
221
        printk("Using transfer index %d, sg offset %d\n", host->transfer_index,sg->offset);
222
        pr_debug("sg = %p\n", sg);
223
        printk("sg = %p\n", sg);
224
 
225
 
226
        host->dma_len = dma_map_sg(mmc_dev(host->mmc), sg, data->sg_len,  DMA_TO_DEVICE);
227
        printk(KERN_ALERT "dma address = %d, sg_dma_len %d, length = %d, sg_dma_len %d\n", sg_dma_address(&data->sg[0]),  sg_dma_len(&data->sg[0]), sg->length, host->dma_len);
228
        for (i = 0; i < host->dma_len; i++) {
229
                unsigned int length = sg_dma_len(&data->sg[i]);
230
 
231
                if (length >= 512)
232
                        length /=512;
233
                else
234
                        length = 1;
235
 
236
                printk(KERN_ALERT "DMA LEN %d\n", length);
237
                //XXX:512 SD 1.0 card only.
238
                for (j = 0; j< length;j++) {
239
                        pr_debug("dma address = %d, length = %d\n", sg_dma_address(&data->sg[i]), sg->length);
240
                        printk(KERN_ALERT "dma address = %d, length = %d, sg_dma_len %d\n", (sg_dma_address(&data->sg[i])+512*j), length, host->dma_len);
241
 
242
                        writel((sg_dma_address(&data->sg[i])+512*j), host->base + BD_TX);
243
                        wmb();
244
                        writel(cmd->arg+off_scal*j, host->base + BD_TX);
245
 
246
                }
247
 
248
        }
249
 
250
        DAT_IRQ_ON (host,(TRE|FIFOE|MRC|TRS));
251
        pr_debug("pre dma read done\n");
252
}
253
 
254 66 tac2
static void ocores_start_cmd(struct ocores_host *host, struct mmc_command *cmd)
255
{
256 69 AlbertVeli
        unsigned int cmd_arg, cmd_command=0;
257 66 tac2
 
258 81 tac2
        struct mmc_data *data = cmd->data;
259 68 tac2
        //WARN_ON(host->cmd != NULL);
260 65 AlbertVeli
        host->cmd = cmd;
261 69 AlbertVeli
 
262 81 tac2
        //XXX:opcode == 51 not supported by hardware, hack here     
263
        if (data && ( cmd->opcode != 51)) {
264
                if ( data->blksz & 0x3 ) {
265
                        pr_debug("Unsupported block size\n");
266
                        cmd->error = -EINVAL;
267
                        mmc_request_done(host->mmc, host->mrq);
268
                        return;
269
                }
270
 
271
                data->bytes_xfered = 0;
272
                host->transfer_index = 0;
273
                host->in_use_index = 0;
274
 
275
                if (data->flags & MMC_DATA_READ){  //Handle a read
276
                        printk(KERN_ALERT "%s: Data read\n", __FUNCTION__);
277
                        host->buffer = NULL;
278
                        host->total_length = 0;
279
                        ocores_pre_dma_read(host); //Set up BD
280
 
281
                }
282
                else if (data->flags & MMC_DATA_WRITE){ //Handle write
283
                        printk(KERN_ALERT "%s: Data write\n", __FUNCTION__);    //cmdr |= AT91_MCI_TRCMD_START;
284
                        /*host->buffer = dma_alloc_coherent(NULL,
285
                                        host->total_length,
286
                                        &host->physical_address, GFP_KERNEL); */
287
                        host->total_length = 0;
288
                        ocores_pre_dma_write(host); //Set up BD
289
 
290
                }
291
 
292
 
293
                if (data->flags & MMC_DATA_STREAM)
294
                        printk(KERN_ALERT "%s: MMC_DATA_STREAM\n", __FUNCTION__);
295
                if (data->blocks > 1)
296
                        printk(KERN_ALERT "%s: data->blocks %d  > 1 \n", __FUNCTION__, data->blocks);
297
 
298
 
299
                        /*
300
                        host->total_length = block_length * blocks;
301
                        host->buffer = dma_alloc_coherent(NULL,
302
                                        host->total_length,
303
                                        &host->physical_address, GFP_KERNEL);
304 71 AlbertVeli
 
305 81 tac2
                        at91_mci_sg_to_dma(host, data);
306 71 AlbertVeli
 
307 81 tac2
                        pr_debug("Transmitting %d bytes\n", host->total_length);
308
 
309
                        at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
310
                        at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
311
                        ier = AT91_MCI_CMDRDY; */
312
 
313
 
314
 
315
 
316 66 tac2
        }
317 81 tac2
        else{
318
                        //Set up command
319
                cmd_arg = cmd->arg;
320
                cmd_command |= cmd->opcode << 8;
321
                cmd_command |= host->word_cnt << 6;
322
 
323
                if ( mmc_resp_type(cmd) == MMC_RSP_CRC  )
324
                        cmd_command |= CRCE;
325
                if ( mmc_resp_type(cmd) == MMC_RSP_OPCODE  )
326
                        cmd_command |= CICE;
327
 
328
                switch (mmc_resp_type(cmd)) {
329
                case MMC_RSP_NONE:
330
                        cmd_command |= MMCOC_RSP_NONE;
331
                        break;
332
                case MMC_RSP_R1:
333
                        cmd_command |= MMCOC_RSP_48;
334
                        break;
335
                case MMC_RSP_R1B:
336
                        cmd_command |= MMCOC_RSP_48;
337
                        break;
338
                case MMC_RSP_R2:
339
                        cmd_command |= MMCOC_RSP_136;
340
                        break;
341
                case MMC_RSP_R3:
342
                        cmd_command |= MMCOC_RSP_48;
343
                        break;
344
                default:
345
                        printk(KERN_INFO "mmc_ocores: unhandled response type %02x\n",
346
                               mmc_resp_type(cmd));
347
                }
348
                 //Send Command
349
                CMD_IRQ_ON (host,(ECC|EEI));
350
                writel(cmd_command, host->base + SD_COMMAND);
351
                wmb();
352
                writel(cmd_arg, host->base + SD_ARG);
353
                printk(KERN_ALERT "%s: cmd_arg = %08x\n", __FUNCTION__, cmd_arg);
354
                printk(KERN_ALERT "%s: cmd_command   = %08x\n", __FUNCTION__, cmd_command);
355
 
356
        }
357
 
358
 
359 71 AlbertVeli
        oc_host=host;
360 72 tac2
 
361 76 tac2
 
362 65 AlbertVeli
}
363 69 AlbertVeli
 
364 66 tac2
static void ocores_process_next(struct ocores_host *host)
365 71 AlbertVeli
{
366
        host->word_cnt=0;
367 66 tac2
        if (!(host->flags & FL_SENT_COMMAND)) {
368
                host->flags |= FL_SENT_COMMAND;
369 69 AlbertVeli
                ocores_start_cmd(host, host->mrq->cmd);
370 66 tac2
        }
371
        else if ((!(host->flags & FL_SENT_STOP)) && host->mrq->stop) {
372
                host->flags |= FL_SENT_STOP;
373
                ocores_start_cmd(host, host->mrq->stop);
374
        }
375
}
376 69 AlbertVeli
 
377 65 AlbertVeli
static void ocores_request(struct mmc_host *mmc, struct mmc_request *mrq)
378
{
379
        struct ocores_host *host = mmc_priv(mmc);
380 69 AlbertVeli
 
381
        //unsigned int cmdr, mr;
382
 
383 65 AlbertVeli
        printk(KERN_ALERT "%s: mrq->cmd->opcode = %08x\n", __FUNCTION__, mrq->cmd->opcode);
384
        printk(KERN_ALERT "%s: mrq->cmd->arg    = %08x\n", __FUNCTION__, mrq->cmd->arg);
385
 
386 66 tac2
        //WARN_ON(host->mrq != NULL);
387 65 AlbertVeli
 
388
        host->mrq = mrq;
389 66 tac2
        host->flags = 0;
390 65 AlbertVeli
 
391 69 AlbertVeli
        ocores_process_next(host);
392
 
393
 
394 66 tac2
        printk(KERN_ALERT "%s: exit\n", __FUNCTION__);
395
}
396 65 AlbertVeli
 
397
 
398
 
399
static int ocores_get_ro(struct mmc_host *mmc)
400
{
401
        /* struct ocores_host *host = mmc_priv(mmc); */
402
 
403
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);
404
 
405 81 tac2
 
406 65 AlbertVeli
        /* /\* Host doesn't support read only detection so assume writeable *\/ */
407
        return 0;
408
}
409
 
410
static void ocores_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
411 69 AlbertVeli
{
412
        struct ocores_host *host = mmc_priv(mmc);
413 66 tac2
        int clk_div, cmd_timeout;
414 65 AlbertVeli
        /* struct ocores_host *host = mmc_priv(mmc); */
415 76 tac2
 
416 65 AlbertVeli
        printk(KERN_ALERT "%s: clock = 0x%08x\n", __FUNCTION__, ios->clock);
417
        printk(KERN_ALERT "%s: vdd = 0x%04x\n", __FUNCTION__, ios->vdd);
418
        printk(KERN_ALERT "%s: bus_mode = 0x%02x\n", __FUNCTION__, ios->bus_mode);
419
        printk(KERN_ALERT "%s: power_mode = 0x%02x\n", __FUNCTION__, ios->power_mode);
420
        printk(KERN_ALERT "%s: bus_width = 0x%02x\n", __FUNCTION__, ios->bus_width);
421
        printk(KERN_ALERT "%s: timing = 0x%02x\n", __FUNCTION__, ios->timing);
422 69 AlbertVeli
 
423 66 tac2
        //Set clock divider and timeout registers
424 69 AlbertVeli
        printk(KERN_ALERT "%s: host->base = %p\n", __FUNCTION__, host->base);
425 66 tac2
        if (ios->clock == 0) {
426 69 AlbertVeli
                //ocores_mci_write (host, SD_SOFTWARE_RST, SD_DISABLE);
427 66 tac2
        }
428 76 tac2
        else if (ios->clock != host->clock)
429
        {
430
                host->clock = ios->clock;
431 66 tac2
                writel(SD_DISABLE, host->base + SD_SOFTWARE_RST);
432
                clk_div = ((SYS_CLK / ios->clock)-2 )/ 2;
433 68 tac2
                cmd_timeout = ((SYS_CLK/ios->clock) * 512);
434 69 AlbertVeli
 
435 66 tac2
                printk(KERN_ALERT " clk_div = 0x%02x\n", clk_div);
436
                printk(KERN_ALERT " cmd_timeout = 0x%02x\n", cmd_timeout);
437 69 AlbertVeli
 
438 66 tac2
                writel (clk_div, host->base  + SD_CLOCK_DIVIDER);
439
                writel (cmd_timeout, host->base  + SD_TIMEOUT);
440 69 AlbertVeli
 
441
 
442 66 tac2
                writel(SD_ENABLE, host->base + SD_SOFTWARE_RST);
443
        }
444 76 tac2
 
445 65 AlbertVeli
}
446
 
447 66 tac2
 
448
 
449
static irqreturn_t ocores_irq_cmd(int irq, void *devid)
450
{
451 73 tac2
         struct ocores_host *host = (struct ocores_host *) devid;
452 71 AlbertVeli
 
453 70 tac2
         disable_irq(host->irq_cmd);
454 71 AlbertVeli
 
455 70 tac2
                //printk(KERN_ALERT "%s: IRQ START***** Normal In  = %08x\n", __FUNCTION__, readl(host->base + SD_NORMAL_INT_STATUS));
456 71 AlbertVeli
 
457 70 tac2
         host->registers.normal_int_status  = readl(host->base + SD_NORMAL_INT_STATUS);
458
         rmb();
459
         host->registers.error_int_status  = readl(host->base + SD_ERROR_INT_STATUS);
460 71 AlbertVeli
 
461 70 tac2
         writel(0,host->base + SD_NORMAL_INT_STATUS);
462
         writel(0,host->base + SD_ERROR_INT_STATUS);
463 71 AlbertVeli
 
464
         //printk(KERN_ALERT "%s: IRQ END***** Error In  = %08x\n", __FUNCTION__, readl(host->base + SD_ERROR_INT_STATUS));
465
         tasklet_schedule(&host->finish_cmd);
466
         CMD_IRQ_OFF (host,(ECC|EEI));
467
         enable_irq(host->irq_cmd);
468
 
469
         return IRQ_HANDLED;
470 66 tac2
}
471
 
472 81 tac2
static irqreturn_t ocores_irq_dat(int irq, void *devid)
473 66 tac2
{
474 81 tac2
         struct ocores_host *host = (struct ocores_host *) devid;
475 66 tac2
 
476 81 tac2
         disable_irq(host->irq_dat);
477
 
478
         printk(KERN_ALERT "%s: DAT IRQ START***** Normal In  = %08x\n", __FUNCTION__, readl(host->base + SD_BD_ISR));
479
 
480
         host->registers.data_int_status  = readl(host->base + SD_BD_ISR);
481
 
482
         writel(0,host->base + SD_BD_ISR);
483
 
484
         tasklet_schedule(&host->finish_data);
485
 
486
         enable_irq(host->irq_dat);
487
 
488
         return IRQ_HANDLED;
489
 
490
 
491
 
492
 
493 66 tac2
}
494 69 AlbertVeli
 
495 65 AlbertVeli
static const struct mmc_host_ops ocores_ops = {
496
        .request                = ocores_request,
497
        .get_ro                 = ocores_get_ro,
498
        .set_ios                = ocores_set_ios,
499
        /* .enable_sdio_irq     = ocores_enable_sdio_irq, */
500
};
501
 
502
static int ocores_probe(struct platform_device *pdev)
503
{
504
        struct mmc_host *mmc;
505
        struct ocores_host *host = NULL;
506
        struct resource *r;
507
        int ret;
508 76 tac2
 
509
 
510 65 AlbertVeli
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);
511
 
512
        r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
513
 
514
        printk(KERN_ALERT "%s: resource %x, %x\n", __FUNCTION__, r->start, r->end);
515
 
516
        r = request_mem_region(r->start, r->end - r->start, DRIVER_NAME);
517
        if (!r) {
518
                return -EBUSY;
519
        }
520
 
521
        mmc = mmc_alloc_host(sizeof(struct ocores_host), &pdev->dev);
522
        if (!mmc) {
523
                ret = -ENOMEM;
524
                goto out;
525
        }
526
 
527 69 AlbertVeli
 
528 65 AlbertVeli
        mmc->ops = &ocores_ops;
529 69 AlbertVeli
 
530 65 AlbertVeli
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
531
        mmc->caps = MMC_CAP_4_BIT_DATA;
532 66 tac2
        mmc->f_min = 700000;  //SYS_CLK  60; 0.7 Mhz
533 69 AlbertVeli
        mmc->f_max = 4166666;  //SYS_CLK;   4.166 666 mhz
534 65 AlbertVeli
 
535 81 tac2
        mmc->max_blk_count =  8;//8; //XXX: 8
536
        mmc->max_hw_segs = 1;
537 65 AlbertVeli
        mmc->max_blk_size = MMCOC_MAX_BLOCK_SIZE;
538 81 tac2
        //mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size;
539
 
540
 
541
        mmc->max_seg_size = PAGE_SIZE;
542 65 AlbertVeli
        mmc->max_req_size = mmc->max_seg_size;
543 81 tac2
        mmc->max_phys_segs = 1; //BD size
544 65 AlbertVeli
 
545
        host = mmc_priv(mmc);
546 76 tac2
 
547
         /*XXX:  */
548
        host->clock = 0;
549
 
550 65 AlbertVeli
        host->mmc = mmc;
551
        host->cmdat = 0;
552 69 AlbertVeli
        host->registers.normal_int_status =0;
553 81 tac2
 
554
        printk("Free FBD \n");
555
        host->free_tx_bd=0;
556
        host->free_rx_bd=0;
557
        printk("Free EBD \n");
558
 
559
 
560
 
561 69 AlbertVeli
        tasklet_init(&host->finish_cmd, ocores_tasklet_finish_cmd,
562
                     (unsigned long) host);
563 81 tac2
 
564
        tasklet_init(&host->finish_data, ocores_tasklet_finish_data,
565
                     (unsigned long) host);
566
 
567 69 AlbertVeli
 
568 65 AlbertVeli
        spin_lock_init(&host->lock);
569
        host->res = r;
570
 
571 66 tac2
        host->base = ioremap(r->start, r->end - r->start +1);
572 65 AlbertVeli
        /* host->base = (void *)r->start; */
573
        if (!host->base) {
574
                ret = -ENOMEM;
575
                goto out;
576
        }
577 81 tac2
        host->free_tx_bd=readl( host->base + BD_STATUS );
578
        host->free_tx_bd=host->free_tx_bd & 0x00ff;
579
        printk("Free TX BD = %d\n", host->free_tx_bd);
580
        host->free_rx_bd=readl( host->base + BD_STATUS );
581
        host->free_rx_bd=(host->free_rx_bd & 0xff00)>>8;
582
        printk("Free TX BD = %d\n", host->free_rx_bd);
583
 
584 65 AlbertVeli
        host->pdata = pdev->dev.platform_data;
585
        mmc->ocr_avail = host->pdata->ocr_mask;
586 69 AlbertVeli
 
587
        host->irq_cmd = platform_get_irq_byname(pdev, "cmd_irq");
588 66 tac2
        ret = request_irq(host->irq_cmd, ocores_irq_cmd, IRQF_DISABLED, DRIVER_NAME, host);
589 69 AlbertVeli
        printk(KERN_ALERT "%s: IRQ dat resource  %x\n", __FUNCTION__, host->irq_cmd );
590
        printk(KERN_ALERT "%s: RET cmd irq %x\n", __FUNCTION__, ret);
591
        if (ret)
592 66 tac2
                goto out;
593
        disable_irq(host->irq_cmd);
594 69 AlbertVeli
 
595 66 tac2
        host->irq_dat = platform_get_irq_byname(pdev, "dat_irq");
596
        ret = request_irq(host->irq_dat, ocores_irq_dat, IRQF_DISABLED, DRIVER_NAME, host);
597 69 AlbertVeli
        printk(KERN_ALERT "%s: IRQ dat resource  %x\n", __FUNCTION__, host->irq_dat );
598
        printk(KERN_ALERT "%s: RET Dat irq  %x\n", __FUNCTION__, ret);
599
        if (ret)
600 66 tac2
                goto out;
601 69 AlbertVeli
        disable_irq(host->irq_dat);
602 65 AlbertVeli
 
603 66 tac2
 
604
 
605 69 AlbertVeli
        enable_irq(host->irq_cmd);
606 66 tac2
        enable_irq(host->irq_dat);
607 65 AlbertVeli
        printk(KERN_ALERT "%s: host->base = %p\n", __FUNCTION__, host->base);
608
        printk(KERN_ALERT "%s: SD_BLOCK = %08x\n", __FUNCTION__, readl(host->base + SD_BLOCK));
609
        printk(KERN_ALERT "%s: host->pdata->ocr_mask = %08x\n", __FUNCTION__, host->pdata->ocr_mask);
610 69 AlbertVeli
        oc_host=host;
611 65 AlbertVeli
        mmc_add_host(mmc);
612
 
613
        printk(KERN_ALERT "%s: exit\n", __FUNCTION__);
614
 
615
        return 0;
616
 
617
 out:
618 66 tac2
        printk(KERN_ALERT "%s: ERROR REQUESTINING RESOURCES\n", __FUNCTION__);
619 65 AlbertVeli
        if (mmc) {
620
                mmc_free_host(mmc);
621
        }
622
        release_resource(r);
623
 
624
        return ret;
625
}
626
 
627 69 AlbertVeli
static void ocores_tasklet_finish_cmd(unsigned long param)
628
{
629
        struct ocores_host *host = (struct ocores_host *) param;
630 81 tac2
 
631
        struct mmc_data *data;
632
        struct scatterlist *sg;
633
        data = host->cmd->data;
634
        sg = &data->sg[0];
635
 
636
        printk(KERN_ALERT " CMD TASKLET RUNNS************\n");
637 69 AlbertVeli
        //Check For Transmissions errors
638
        if ((host->registers.normal_int_status & EI) == EI)
639
        {
640
                printk(KERN_ALERT "TRANSMISSION ERROR DETECTED");
641
                switch ( host->registers.error_int_status )
642
                {
643
                case (CTE):
644
                        pr_debug("Card took too long to respond\n");
645
                        host->mrq->cmd->error = -ETIMEDOUT ;
646
                        break;
647
                case (CCRC  ):
648
                        pr_debug(" CRC  problem with the received or sent data\n");
649
                        host->mrq->cmd->error = -EILSEQ;
650
                        break;
651
                case (CIE  ):
652
                        pr_debug("Index problem with the received or sent data\n");
653
                        host->mrq->cmd->error = -EILSEQ;
654
                        break;
655
                }
656 76 tac2
 
657
                mmc_request_done(host->mmc, host->mrq);
658 69 AlbertVeli
        }
659
        else
660 73 tac2
        {
661 74 tac2
                if ( mmc_resp_type(host->mrq->cmd) == MMC_RSP_R2      )   //Long response
662 71 AlbertVeli
                {
663 75 tac2
                        printk(KERN_ALERT "Long Response, Word Cnt %d, RESP  * = %08x\n ",host->word_cnt,readl(host->base + SD_RESP1));
664
 
665 81 tac2
                        if (host->mrq->cmd->opcode == 2) { //XXX: Hack until supported long response
666 77 tac2
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
667 81 tac2
                                host->mrq->cmd->resp[1]  =  0x01302331;
668
                                host->mrq->cmd->resp[2]  =  0x195abdef;
669
                                host->mrq->cmd->resp[3]  =  0x195abdef;
670 76 tac2
                                mmc_request_done(host->mmc, host->mrq);
671 81 tac2
                        } //XXX: Hack until supported long response
672
                        else if(host->mrq->cmd->opcode == 51)
673 80 tac2
                        {
674 81 tac2
                                host->mrq->cmd->resp[0] = 0x900;
675
                                host->mrq->cmd->resp[1] = 0xaaa;
676
                                host->mrq->cmd->resp[2] = 0xbbb;
677
                                host->mrq->cmd->resp[3] = 0xccc;
678
                                host->mrq->data->bytes_xfered =8;
679
                                dma_unmap_sg(mmc_dev(host->mmc), sg, data->sg_len, DMA_FROM_DEVICE);
680 80 tac2
                                mmc_request_done(host->mmc, host->mrq);
681 81 tac2
                        }
682 80 tac2
 
683 81 tac2
 
684
 
685 75 tac2
                        else {
686
                                host->word_cnt+=1;
687
                                switch(host->word_cnt-1)
688
                                {
689
                                case (0):
690 80 tac2
                                        host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
691 75 tac2
                                        ocores_start_cmd(host, host->mrq->cmd);
692
                                        break;
693
                                case (1):
694 80 tac2
                                        host->mrq->cmd->resp[1]  =  readl(host->base + SD_RESP1);
695 75 tac2
                                        ocores_start_cmd(host, host->mrq->cmd);
696
                                        break;
697
                                case (2):
698 80 tac2
                                        host->mrq->cmd->resp[2]  =  readl(host->base + SD_RESP1);
699 75 tac2
                                        ocores_start_cmd(host, host->mrq->cmd);
700
                                        break;
701
                                case (3):
702 80 tac2
                                        host->mrq->cmd->resp[3]  =  readl(host->base + SD_RESP1);
703 75 tac2
                                        mmc_request_done(host->mmc, host->mrq);
704
                                        break;
705
                                }
706
                        }
707 71 AlbertVeli
                }
708
                else  //Short response
709
                {
710
                        host->mrq->cmd->error = 0 ;
711
                        host->mrq->cmd->resp[0] = readl(host->base + SD_RESP1);
712
                        printk(KERN_ALERT "Short Response CMD RSP * = %08x\n", host->mrq->cmd->resp[0]);
713
                        mmc_request_done(host->mmc, host->mrq);
714
                }
715 69 AlbertVeli
        }
716 72 tac2
 
717 69 AlbertVeli
}
718 81 tac2
static void ocores_tasklet_finish_data(unsigned long param)
719
{
720
        struct ocores_host *host = (struct ocores_host *) param;
721
 
722
 
723
        struct mmc_data *data;
724
        struct scatterlist *sg;
725
        int free_bd,i;
726
        int *adr;
727
        data = host->cmd->data;
728
        sg = &data->sg[0]; //XXX:O Change to dynamic later?
729
 
730
        printk(KERN_ALERT " DATA TASKLET RUNNS************\n");
731
 
732
        //IF read operation
733
 
734
        if ((host->registers.data_int_status & TRS) == TRS){
735
                if (data->flags & MMC_DATA_READ){
736
                        free_bd=readl( host->base + BD_STATUS );
737
                        free_bd=(free_bd&0xff00)>>8;
738
                        printk(KERN_ALERT " DATA TASKLET RUNNS*** Free BD %d\n", free_bd);
739
                        if (free_bd == host->free_tx_bd) {
740
                                dma_unmap_sg(mmc_dev(host->mmc), sg, sg->length, DMA_FROM_DEVICE);
741
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
742
                                data->bytes_xfered = sg->length;
743
                                DAT_IRQ_OFF (host,(TRE|FIFOE|MRC|TRS));
744
                                mmc_request_done(host->mmc, host->mrq);
745
                        }
746
                } else if (data->flags & MMC_DATA_WRITE){
747
                        free_bd=readl( host->base + BD_STATUS );
748
                        free_bd=(free_bd&0x00FF);
749
                        printk(KERN_ALERT " DATA TASKLET RUNNS*** Free BD %d\n", free_bd);
750
                        if (free_bd == host->free_tx_bd) {
751
                                dma_unmap_sg(mmc_dev(host->mmc), sg, sg->length, DMA_TO_DEVICE);
752
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
753
                                data->bytes_xfered = sg->length;
754
                                DAT_IRQ_OFF (host,(TRE|FIFOE|MRC|TRS));
755
                                mmc_request_done(host->mmc, host->mrq);
756
                        }
757
 
758
                }
759
 
760
        }
761
        else {
762
                sg= &data->sg[0];
763
                writel(SD_DISABLE, host->base + SD_SOFTWARE_RST);
764
                writel(SD_ENABLE, host->base + SD_SOFTWARE_RST);
765
 
766
                        if ((host->registers.data_int_status & MRC) == MRC)
767
                                host->data->error = -ETIMEDOUT;
768
                        if ((host->registers.data_int_status &  CMDE) ==  CMDE)
769
                                host->data->error = -EILSEQ;
770
                        data->bytes_xfered =0;
771
 
772
                dma_unmap_sg(mmc_dev(host->mmc), sg, data->sg_len, DMA_FROM_DEVICE);
773
                DAT_IRQ_OFF (host,(TRE|FIFOE|MRC|TRS));
774
                mmc_request_done(host->mmc, host->mrq);
775
 
776
 
777
        }
778
 
779
 
780
 
781
 
782
 
783
 
784
 
785 69 AlbertVeli
 
786 81 tac2
}
787 65 AlbertVeli
static int ocores_remove(struct platform_device *pdev)
788
{
789
        struct mmc_host *mmc = platform_get_drvdata(pdev);
790
 
791
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);
792
 
793
        platform_set_drvdata(pdev, NULL);
794
 
795
        if (mmc) {
796
                struct ocores_host *host = mmc_priv(mmc);
797
 
798
                mmc_remove_host(mmc);
799
 
800
                release_resource(host->res);
801
 
802
                mmc_free_host(mmc);
803
        }
804
 
805
        printk(KERN_ALERT "%s: exit\n", __FUNCTION__);
806
 
807
        return 0;
808
}
809
 
810
#ifdef CONFIG_PM
811
static int ocores_suspend(struct platform_device *dev, pm_message_t state)
812
{
813
        struct mmc_host *mmc = platform_get_drvdata(dev);
814
        int ret = 0;
815
 
816
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);
817
 
818
        if (mmc) {
819
                ret = mmc_suspend_host(mmc, state);
820
        }
821
 
822
        printk(KERN_ALERT "%s: exit\n", __FUNCTION__);
823
 
824
        return ret;
825
}
826
 
827
static int ocores_resume(struct platform_device *dev)
828
{
829
        struct mmc_host *mmc = platform_get_drvdata(dev);
830
        int ret = 0;
831
 
832
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);
833
 
834
        if (mmc) {
835
                ret = mmc_resume_host(mmc);
836
        }
837
 
838
        printk(KERN_ALERT "%s: exit\n", __FUNCTION__);
839
 
840
        return ret;
841
}
842
#else
843
#define ocores_suspend  NULL
844
#define ocores_resume   NULL
845
#endif
846
 
847
static struct platform_driver ocores_driver = {
848
        .probe          = ocores_probe,
849
        .remove         = ocores_remove,
850
        .suspend        = ocores_suspend,
851
        .resume         = ocores_resume,
852
        .driver         = {
853
                .name   = DRIVER_NAME,
854
        },
855
};
856
 
857
static int __init ocores_init(void)
858
{
859
        printk(KERN_ALERT "%s: registering ocores platform_driver\n", __FUNCTION__);
860
 
861
        return platform_driver_register(&ocores_driver);
862
}
863
 
864
static void __exit ocores_exit(void)
865
{
866
        printk(KERN_ALERT "%s: unregistering ocores platform_driver\n", __FUNCTION__);
867
 
868
        platform_driver_unregister(&ocores_driver);
869
}
870
 
871
module_init(ocores_init);
872
module_exit(ocores_exit);
873
 
874
MODULE_DESCRIPTION("OpenCores Multimedia Card Interface Driver");
875
MODULE_LICENSE("GPL");

powered by: WebSVN 2.1.0

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