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 82

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

powered by: WebSVN 2.1.0

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