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] - Diff between revs 80 and 81

Go to most recent revision | Show entire file | Details | Blame | View Log

Rev 80 Rev 81
Line 1... Line 1...
/* -*- linux-c -*-
/* -*- linux-c -*-
 *
 *
 * OpenCores MMC Controller driver
 * OpenCores MMC Controller driver
 *
 *
 
 *
 
 * Command 51 and Command 2 hardcoded
 
 *
 
 *
 
 *
 * Copyright (C) 2009 ORSoC, All Rights Reserved.
 * Copyright (C) 2009 ORSoC, All Rights Reserved.
 *
 *
 * This program is free software; you can redistribute it and/or modify it
 * This program is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License as published
 * under the terms of the GNU General Public License as published
 * by the Free Software Foundation; version 2 of the License.
 * by the Free Software Foundation; version 2 of the License.
Line 23... Line 28...
#include <linux/platform_device.h>
#include <linux/platform_device.h>
#include <linux/delay.h>
#include <linux/delay.h>
#include <linux/interrupt.h>
#include <linux/interrupt.h>
#include <linux/err.h>
#include <linux/err.h>
#include <linux/mmc/host.h>
#include <linux/mmc/host.h>
 
#include <linux/dma-mapping.h>
 
#include <linux/scatterlist.h>
 
#include <linux/highmem.h>
#include <asm/board.h>
#include <asm/board.h>
#include <asm/io.h>
#include <asm/io.h>
 
#include <asm/irq.h>
#include <asm/mmc.h>
#include <asm/mmc.h>
#include <asm/system.h>
#include <asm/system.h>
 
#include <linux/mmc/card.h>
#include "mmc_ocores.h"
#include "mmc_ocores.h"
 
 
#define DRIVER_NAME "mmc-ocores"
#define DRIVER_NAME "mmc-ocores"
 
 
#define NR_SG   1
#define NR_SG   1
 
 
 
 
 
 
 
 
struct ocores_host {
struct ocores_host {
        struct mmc_host         *mmc;
        struct mmc_host         *mmc;
        spinlock_t              lock;
        spinlock_t              lock;
        struct resource         *res;
        struct resource         *res;
        void __iomem            *base;
        void __iomem            *base;
Line 52... Line 62...
        struct mmc_data         *data;
        struct mmc_data         *data;
        int irq_cmd;
        int irq_cmd;
        int irq_dat;
        int irq_dat;
        unsigned int flags;
        unsigned int flags;
        struct tasklet_struct finish_cmd;
        struct tasklet_struct finish_cmd;
 
        struct tasklet_struct finish_data;
        struct {
        struct {
                unsigned int normal_int_status;
                unsigned int normal_int_status;
                unsigned int error_int_status;
                unsigned int error_int_status;
 
                unsigned int data_int_status;
        } registers;
        } registers;
        int clock;
        int clock;
 
 
 
        /* DMA buffer used for transmitting */
 
        unsigned int* buffer;
 
        dma_addr_t physical_address;
 
        unsigned int total_length;
 
        unsigned int            dma_len;
 
        /* Latest in the scatterlist that has been enabled for transfer, but not freed */
 
        int in_use_index;
 
 
 
        /* Latest in the scatterlist that has been enabled for transfer */
 
        int transfer_index;
 
        int free_tx_bd;
 
        int free_rx_bd;
};
};
 
 
struct ocores_host *oc_host;
struct ocores_host *oc_host;
 
 
static void ocores_tasklet_finish_cmd(unsigned long param);
static void ocores_tasklet_finish_cmd(unsigned long param);
 
static void ocores_tasklet_finish_data(unsigned long param);
 
 
static inline void CMD_IRQ_ON(struct ocores_host *host, u32 mask)
static inline void CMD_IRQ_ON(struct ocores_host *host, u32 mask)
{
{
        u32 val = readl(host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
        u32 val = readl(host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
        printk(KERN_ALERT "Int mask = %08x\n", val);
 
        val |= mask;
        val |= mask;
        writel (val, host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
        writel (val, host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
        printk(KERN_ALERT "Int mask = %08x\n", val);
 
}
}
 
 
static inline void CMD_IRQ_OFF(struct ocores_host *host, u32 mask)
static inline void CMD_IRQ_OFF(struct ocores_host *host, u32 mask)
{
{
        u32 val = readl(host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
        u32 val = readl(host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
        val  &= ~mask;
        val  &= ~mask;
        writel (val, host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
        writel (val, host->base  + SD_NOMAL_INT_SIGNAL_ENABLE);
}
}
 
 
 
static inline void DAT_IRQ_ON(struct ocores_host *host, u32 mask)
 
{
 
        u32 val = readl(host->base  + SD_BD_ISER);
 
        val |= mask;
 
        writel (val, host->base  + SD_BD_ISER);
 
}
 
 
 
static inline void DAT_IRQ_OFF(struct ocores_host *host, u32 mask)
 
{
 
        u32 val = readl(host->base  + SD_BD_ISER);
 
        val  &= ~mask;
 
        writel (val, host->base  + SD_BD_ISER);
 
}
 
 
 
 
 
static void ocores_pre_dma_read(struct ocores_host *host)
 
{
 
        int i,j;
 
        int off_scal;
 
        struct scatterlist *sg;
 
        struct mmc_command *cmd;
 
        struct mmc_data *data;
 
 
 
        off_scal=512;
 
        if (host->mmc->card!= NULL){
 
 
 
                if (mmc_card_blockaddr(host->mmc->card))
 
                        off_scal=1;
 
                else
 
                        off_scal=512;
 
        }
 
        printk("pre dma read off %d\n", off_scal);
 
 
 
        cmd = host->cmd;
 
        if (!cmd) {
 
                pr_debug("no command\n");
 
                return;
 
        }
 
        data = cmd->data;
 
        if (!data) {
 
                pr_debug("no data\n");
 
                return;
 
        }
 
 
 
        /* Setup the next transfer */
 
        pr_debug("Using transfer index %d\n", host->transfer_index);
 
 
 
        sg = &data->sg[host->transfer_index++];
 
        printk("Using transfer index %d, sg offset %d\n", host->transfer_index,sg->offset);
 
        pr_debug("sg = %p\n", sg);
 
        printk("sg = %p\n", sg);
 
 
 
 
 
        host->dma_len = dma_map_sg(mmc_dev(host->mmc), sg, data->sg_len,  DMA_FROM_DEVICE);
 
        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);
 
        for (i = 0; i < host->dma_len; i++) {
 
                unsigned int length = sg_dma_len(&data->sg[i]);
 
 
 
                if (length >= 512)
 
                        length /=512;
 
                else
 
                        length = 1;
 
 
 
                printk(KERN_ALERT "DMA LEN %d\n", length);
 
                //XXX:512 SD 1.0 card only.
 
                for (j = 0; j< length;j++) {
 
                        pr_debug("dma address = %d, length = %d\n", sg_dma_address(&data->sg[i]), sg->length);
 
                        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);
 
 
 
                        writel((sg_dma_address(&data->sg[i])+512*j), host->base + BD_RX);
 
                        wmb();
 
                        writel(cmd->arg+off_scal*j, host->base + BD_RX);
 
 
 
                }
 
 
 
        }
 
 
 
        DAT_IRQ_ON (host,(TRE|FIFOE|MRC|TRS));
 
        pr_debug("pre dma read done\n");
 
}
 
static void ocores_pre_dma_write(struct ocores_host *host)
 
{
 
        int i,j;
 
        int off_scal;
 
        struct scatterlist *sg;
 
        struct mmc_command *cmd;
 
        struct mmc_data *data;
 
 
 
        off_scal=512;
 
        if (host->mmc->card!= NULL){
 
 
 
                if (mmc_card_blockaddr(host->mmc->card))
 
                        off_scal=1;
 
                else
 
                        off_scal=512;
 
        }
 
        printk("pre dma write off %d\n", off_scal);
 
 
 
        cmd = host->cmd;
 
        if (!cmd) {
 
                pr_debug("no command\n");
 
                return;
 
        }
 
        data = cmd->data;
 
        if (!data) {
 
                pr_debug("no data\n");
 
                return;
 
        }
 
 
 
        /* Setup the next transfer */
 
        pr_debug("Using transfer index %d\n", host->transfer_index);
 
 
 
        sg = &data->sg[host->transfer_index++];
 
        printk("Using transfer index %d, sg offset %d\n", host->transfer_index,sg->offset);
 
        pr_debug("sg = %p\n", sg);
 
        printk("sg = %p\n", sg);
 
 
 
 
 
        host->dma_len = dma_map_sg(mmc_dev(host->mmc), sg, data->sg_len,  DMA_TO_DEVICE);
 
        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);
 
        for (i = 0; i < host->dma_len; i++) {
 
                unsigned int length = sg_dma_len(&data->sg[i]);
 
 
 
                if (length >= 512)
 
                        length /=512;
 
                else
 
                        length = 1;
 
 
 
                printk(KERN_ALERT "DMA LEN %d\n", length);
 
                //XXX:512 SD 1.0 card only.
 
                for (j = 0; j< length;j++) {
 
                        pr_debug("dma address = %d, length = %d\n", sg_dma_address(&data->sg[i]), sg->length);
 
                        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);
 
 
 
                        writel((sg_dma_address(&data->sg[i])+512*j), host->base + BD_TX);
 
                        wmb();
 
                        writel(cmd->arg+off_scal*j, host->base + BD_TX);
 
 
 
                }
 
 
 
        }
 
 
 
        DAT_IRQ_ON (host,(TRE|FIFOE|MRC|TRS));
 
        pr_debug("pre dma read done\n");
 
}
 
 
static void ocores_start_cmd(struct ocores_host *host, struct mmc_command *cmd)
static void ocores_start_cmd(struct ocores_host *host, struct mmc_command *cmd)
{
{
        unsigned int cmd_arg, cmd_command=0;
        unsigned int cmd_arg, cmd_command=0;
 
 
        //struct mmc_data *data = cmd->data;
        struct mmc_data *data = cmd->data;
        //WARN_ON(host->cmd != NULL);
        //WARN_ON(host->cmd != NULL);
        host->cmd = cmd;
        host->cmd = cmd;
 
 
 
        //XXX:opcode == 51 not supported by hardware, hack here     
 
        if (data && ( cmd->opcode != 51)) {
 
                if ( data->blksz & 0x3 ) {
 
                        pr_debug("Unsupported block size\n");
 
                        cmd->error = -EINVAL;
 
                        mmc_request_done(host->mmc, host->mrq);
 
                        return;
 
                }
 
 
 
                data->bytes_xfered = 0;
 
                host->transfer_index = 0;
 
                host->in_use_index = 0;
 
 
 
                if (data->flags & MMC_DATA_READ){  //Handle a read
 
                        printk(KERN_ALERT "%s: Data read\n", __FUNCTION__);
 
                        host->buffer = NULL;
 
                        host->total_length = 0;
 
                        ocores_pre_dma_read(host); //Set up BD
 
 
 
                }
 
                else if (data->flags & MMC_DATA_WRITE){ //Handle write
 
                        printk(KERN_ALERT "%s: Data write\n", __FUNCTION__);    //cmdr |= AT91_MCI_TRCMD_START;
 
                        /*host->buffer = dma_alloc_coherent(NULL,
 
                                        host->total_length,
 
                                        &host->physical_address, GFP_KERNEL); */
 
                        host->total_length = 0;
 
                        ocores_pre_dma_write(host); //Set up BD
 
 
 
                }
 
 
 
 
 
                if (data->flags & MMC_DATA_STREAM)
 
                        printk(KERN_ALERT "%s: MMC_DATA_STREAM\n", __FUNCTION__);
 
                if (data->blocks > 1)
 
                        printk(KERN_ALERT "%s: data->blocks %d  > 1 \n", __FUNCTION__, data->blocks);
 
 
 
 
 
                        /*
 
                        host->total_length = block_length * blocks;
 
                        host->buffer = dma_alloc_coherent(NULL,
 
                                        host->total_length,
 
                                        &host->physical_address, GFP_KERNEL);
 
 
 
                        at91_mci_sg_to_dma(host, data);
 
 
 
                        pr_debug("Transmitting %d bytes\n", host->total_length);
 
 
 
                        at91_mci_write(host, ATMEL_PDC_TPR, host->physical_address);
 
                        at91_mci_write(host, ATMEL_PDC_TCR, host->total_length / 4);
 
                        ier = AT91_MCI_CMDRDY; */
 
 
 
 
 
 
 
 
 
        }
 
        else{
        //Set up command
        //Set up command
        cmd_arg = cmd->arg;
        cmd_arg = cmd->arg;
        cmd_command |= cmd->opcode << 8;
        cmd_command |= cmd->opcode << 8;
        cmd_command |= host->word_cnt << 6;
        cmd_command |= host->word_cnt << 6;
 
 
Line 116... Line 343...
                break;
                break;
        default:
        default:
                printk(KERN_INFO "mmc_ocores: unhandled response type %02x\n",
                printk(KERN_INFO "mmc_ocores: unhandled response type %02x\n",
                       mmc_resp_type(cmd));
                       mmc_resp_type(cmd));
        }
        }
 
                 //Send Command
     /*If data
                CMD_IRQ_ON (host,(ECC|EEI));
    //  if ( data->blksz & 0x3 ) {
                writel(cmd_command, host->base + SD_COMMAND);
                        pr_debug("Unsupported block size\n");
                wmb();
                        cmd->error = -EINVAL;
                writel(cmd_arg, host->base + SD_ARG);
                        mmc_request_done(host->mmc, host->request);
 
                        return;
 
                } */
 
 
 
        printk(KERN_ALERT "%s: cmd_arg = %08x\n", __FUNCTION__, cmd_arg);
        printk(KERN_ALERT "%s: cmd_arg = %08x\n", __FUNCTION__, cmd_arg);
        printk(KERN_ALERT "%s: cmd_command   = %08x\n", __FUNCTION__, cmd_command);
        printk(KERN_ALERT "%s: cmd_command   = %08x\n", __FUNCTION__, cmd_command);
 
 
 
        }
 
 
 
 
        oc_host=host;
        oc_host=host;
 
 
 
 
        CMD_IRQ_ON (host,(ECC|EEI));
 
        writel(cmd_command, host->base + SD_COMMAND);
 
        wmb();
 
        writel(cmd_arg, host->base + SD_ARG);
 
}
}
 
 
static void ocores_process_next(struct ocores_host *host)
static void ocores_process_next(struct ocores_host *host)
{
{
        host->word_cnt=0;
        host->word_cnt=0;
Line 177... Line 400...
{
{
        /* struct ocores_host *host = mmc_priv(mmc); */
        /* struct ocores_host *host = mmc_priv(mmc); */
 
 
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);
 
 
        /* if (host->pdata && host->pdata->get_ro) */
 
        /*      return host->pdata->get_ro(mmc_dev(mmc)); */
 
        /* /\* Host doesn't support read only detection so assume writeable *\/ */
        /* /\* Host doesn't support read only detection so assume writeable *\/ */
        return 0;
        return 0;
}
}
 
 
static void ocores_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
static void ocores_set_ios(struct mmc_host *mmc, struct mmc_ios *ios)
Line 245... Line 467...
         enable_irq(host->irq_cmd);
         enable_irq(host->irq_cmd);
 
 
         return IRQ_HANDLED;
         return IRQ_HANDLED;
}
}
 
 
static irqreturn_t ocores_irq_dat(int irq, void *dev_id)
static irqreturn_t ocores_irq_dat(int irq, void *devid)
{
{
 
         struct ocores_host *host = (struct ocores_host *) devid;
 
 
 
         disable_irq(host->irq_dat);
 
 
 
         printk(KERN_ALERT "%s: DAT IRQ START***** Normal In  = %08x\n", __FUNCTION__, readl(host->base + SD_BD_ISR));
 
 
 
         host->registers.data_int_status  = readl(host->base + SD_BD_ISR);
 
 
 
         writel(0,host->base + SD_BD_ISR);
 
 
 
         tasklet_schedule(&host->finish_data);
 
 
 
         enable_irq(host->irq_dat);
 
 
 
         return IRQ_HANDLED;
 
 
 
 
 
 
 
 
}
}
 
 
static const struct mmc_host_ops ocores_ops = {
static const struct mmc_host_ops ocores_ops = {
        .request                = ocores_request,
        .request                = ocores_request,
Line 290... Line 530...
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
        mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34;
        mmc->caps = MMC_CAP_4_BIT_DATA;
        mmc->caps = MMC_CAP_4_BIT_DATA;
        mmc->f_min = 700000;  //SYS_CLK  60; 0.7 Mhz
        mmc->f_min = 700000;  //SYS_CLK  60; 0.7 Mhz
        mmc->f_max = 4166666;  //SYS_CLK;   4.166 666 mhz
        mmc->f_max = 4166666;  //SYS_CLK;   4.166 666 mhz
 
 
        mmc->max_blk_count = 8;
        mmc->max_blk_count =  8;//8; //XXX: 8
        mmc->max_hw_segs = mmc->max_blk_count;
        mmc->max_hw_segs = 1;
        mmc->max_blk_size = MMCOC_MAX_BLOCK_SIZE;
        mmc->max_blk_size = MMCOC_MAX_BLOCK_SIZE;
        mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size;
        //mmc->max_seg_size = mmc->max_blk_count * mmc->max_blk_size;
 
 
 
 
 
        mmc->max_seg_size = PAGE_SIZE;
        mmc->max_req_size = mmc->max_seg_size;
        mmc->max_req_size = mmc->max_seg_size;
        mmc->max_phys_segs = mmc->max_hw_segs;
        mmc->max_phys_segs = 1; //BD size
 
 
        host = mmc_priv(mmc);
        host = mmc_priv(mmc);
 
 
         /*XXX:  */
         /*XXX:  */
        host->clock = 0;
        host->clock = 0;
 
 
        host->mmc = mmc;
        host->mmc = mmc;
        host->cmdat = 0;
        host->cmdat = 0;
        host->registers.normal_int_status =0;
        host->registers.normal_int_status =0;
 
 
 
        printk("Free FBD \n");
 
        host->free_tx_bd=0;
 
        host->free_rx_bd=0;
 
        printk("Free EBD \n");
 
 
 
 
 
 
        tasklet_init(&host->finish_cmd, ocores_tasklet_finish_cmd,
        tasklet_init(&host->finish_cmd, ocores_tasklet_finish_cmd,
                     (unsigned long) host);
                     (unsigned long) host);
 
 
 
        tasklet_init(&host->finish_data, ocores_tasklet_finish_data,
 
                     (unsigned long) host);
 
 
 
 
        spin_lock_init(&host->lock);
        spin_lock_init(&host->lock);
        host->res = r;
        host->res = r;
 
 
        host->base = ioremap(r->start, r->end - r->start +1);
        host->base = ioremap(r->start, r->end - r->start +1);
        /* host->base = (void *)r->start; */
        /* host->base = (void *)r->start; */
        if (!host->base) {
        if (!host->base) {
                ret = -ENOMEM;
                ret = -ENOMEM;
                goto out;
                goto out;
        }
        }
 
        host->free_tx_bd=readl( host->base + BD_STATUS );
 
        host->free_tx_bd=host->free_tx_bd & 0x00ff;
 
        printk("Free TX BD = %d\n", host->free_tx_bd);
 
        host->free_rx_bd=readl( host->base + BD_STATUS );
 
        host->free_rx_bd=(host->free_rx_bd & 0xff00)>>8;
 
        printk("Free TX BD = %d\n", host->free_rx_bd);
 
 
        host->pdata = pdev->dev.platform_data;
        host->pdata = pdev->dev.platform_data;
        mmc->ocr_avail = host->pdata->ocr_mask;
        mmc->ocr_avail = host->pdata->ocr_mask;
 
 
        host->irq_cmd = platform_get_irq_byname(pdev, "cmd_irq");
        host->irq_cmd = platform_get_irq_byname(pdev, "cmd_irq");
        ret = request_irq(host->irq_cmd, ocores_irq_cmd, IRQF_DISABLED, DRIVER_NAME, host);
        ret = request_irq(host->irq_cmd, ocores_irq_cmd, IRQF_DISABLED, DRIVER_NAME, host);
Line 366... Line 626...
 
 
static void ocores_tasklet_finish_cmd(unsigned long param)
static void ocores_tasklet_finish_cmd(unsigned long param)
{
{
        struct ocores_host *host = (struct ocores_host *) param;
        struct ocores_host *host = (struct ocores_host *) param;
 
 
        printk(KERN_ALERT " TASKLET RUNNS************\n");
        struct mmc_data *data;
 
        struct scatterlist *sg;
        printk(KERN_ALERT "%s: TASKLET RUNNS****** Normal INT = %08x\n", __FUNCTION__,  host->registers.normal_int_status);
        data = host->cmd->data;
        printk(KERN_ALERT "%s: TASKLET RUNNS****** Error INT = %08x\n", __FUNCTION__,  host->registers.error_int_status);
        sg = &data->sg[0];
 
 
 
        printk(KERN_ALERT " CMD TASKLET RUNNS************\n");
        //Check For Transmissions errors
        //Check For Transmissions errors
        if ((host->registers.normal_int_status & EI) == EI)
        if ((host->registers.normal_int_status & EI) == EI)
        {
        {
                printk(KERN_ALERT "TRANSMISSION ERROR DETECTED");
                printk(KERN_ALERT "TRANSMISSION ERROR DETECTED");
                switch ( host->registers.error_int_status )
                switch ( host->registers.error_int_status )
Line 399... Line 660...
        {
        {
                if ( mmc_resp_type(host->mrq->cmd) == MMC_RSP_R2      )   //Long response
                if ( mmc_resp_type(host->mrq->cmd) == MMC_RSP_R2      )   //Long response
                {
                {
                        printk(KERN_ALERT "Long Response, Word Cnt %d, RESP  * = %08x\n ",host->word_cnt,readl(host->base + SD_RESP1));
                        printk(KERN_ALERT "Long Response, Word Cnt %d, RESP  * = %08x\n ",host->word_cnt,readl(host->base + SD_RESP1));
 
 
                        if (host->mrq->cmd->opcode == 2) {
                        if (host->mrq->cmd->opcode == 2) { //XXX: Hack until supported long response
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
                                host->mrq->cmd->resp[1]  =  0xaaaaaaaa;
                                host->mrq->cmd->resp[1]  =  0x01302331;
                                host->mrq->cmd->resp[2]  =  0xbbbbbbbb;
                                host->mrq->cmd->resp[2]  =  0x195abdef;
                                host->mrq->cmd->resp[3]  =  0;
                                host->mrq->cmd->resp[3]  =  0x195abdef;
                                mmc_request_done(host->mmc, host->mrq);
                                mmc_request_done(host->mmc, host->mrq);
                        } //XXX:
                        } //XXX: Hack until supported long response
                        else if(host->mrq->cmd->opcode == 9)
                        else if(host->mrq->cmd->opcode == 51)
                        {
                        {
                                host->mrq->cmd->resp[0]  =  0x006f0032;
                                host->mrq->cmd->resp[0] = 0x900;
                                host->mrq->cmd->resp[1]  =  0x5b5983bf;
                                host->mrq->cmd->resp[1] = 0xaaa;
                                host->mrq->cmd->resp[2]  =  0xf6dbdfff;
                                host->mrq->cmd->resp[2] = 0xbbb;
                                host->mrq->cmd->resp[3]  =  0x0a4041ff;
                                host->mrq->cmd->resp[3] = 0xccc;
 
                                host->mrq->data->bytes_xfered =8;
 
                                dma_unmap_sg(mmc_dev(host->mmc), sg, data->sg_len, DMA_FROM_DEVICE);
                                mmc_request_done(host->mmc, host->mrq);
                                mmc_request_done(host->mmc, host->mrq);
                        }
                        }
 
 
 
 
 
 
                        else {
                        else {
                                host->word_cnt+=1;
                                host->word_cnt+=1;
                                switch(host->word_cnt-1)
                                switch(host->word_cnt-1)
                                {
                                {
                                case (0):
                                case (0):
Line 448... Line 713...
                        mmc_request_done(host->mmc, host->mrq);
                        mmc_request_done(host->mmc, host->mrq);
                }
                }
        }
        }
 
 
}
}
 
static void ocores_tasklet_finish_data(unsigned long param)
 
{
 
        struct ocores_host *host = (struct ocores_host *) param;
 
 
 
 
 
        struct mmc_data *data;
 
        struct scatterlist *sg;
 
        int free_bd,i;
 
        int *adr;
 
        data = host->cmd->data;
 
        sg = &data->sg[0]; //XXX:O Change to dynamic later?
 
 
 
        printk(KERN_ALERT " DATA TASKLET RUNNS************\n");
 
 
 
        //IF read operation
 
 
 
        if ((host->registers.data_int_status & TRS) == TRS){
 
                if (data->flags & MMC_DATA_READ){
 
                        free_bd=readl( host->base + BD_STATUS );
 
                        free_bd=(free_bd&0xff00)>>8;
 
                        printk(KERN_ALERT " DATA TASKLET RUNNS*** Free BD %d\n", free_bd);
 
                        if (free_bd == host->free_tx_bd) {
 
                                dma_unmap_sg(mmc_dev(host->mmc), sg, sg->length, DMA_FROM_DEVICE);
 
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
 
                                data->bytes_xfered = sg->length;
 
                                DAT_IRQ_OFF (host,(TRE|FIFOE|MRC|TRS));
 
                                mmc_request_done(host->mmc, host->mrq);
 
                        }
 
                } else if (data->flags & MMC_DATA_WRITE){
 
                        free_bd=readl( host->base + BD_STATUS );
 
                        free_bd=(free_bd&0x00FF);
 
                        printk(KERN_ALERT " DATA TASKLET RUNNS*** Free BD %d\n", free_bd);
 
                        if (free_bd == host->free_tx_bd) {
 
                                dma_unmap_sg(mmc_dev(host->mmc), sg, sg->length, DMA_TO_DEVICE);
 
                                host->mrq->cmd->resp[0]  =  readl(host->base + SD_RESP1);
 
                                data->bytes_xfered = sg->length;
 
                                DAT_IRQ_OFF (host,(TRE|FIFOE|MRC|TRS));
 
                                mmc_request_done(host->mmc, host->mrq);
 
                        }
 
 
 
                }
 
 
 
        }
 
        else {
 
                sg= &data->sg[0];
 
                writel(SD_DISABLE, host->base + SD_SOFTWARE_RST);
 
                writel(SD_ENABLE, host->base + SD_SOFTWARE_RST);
 
 
 
                        if ((host->registers.data_int_status & MRC) == MRC)
 
                                host->data->error = -ETIMEDOUT;
 
                        if ((host->registers.data_int_status &  CMDE) ==  CMDE)
 
                                host->data->error = -EILSEQ;
 
                        data->bytes_xfered =0;
 
 
 
                dma_unmap_sg(mmc_dev(host->mmc), sg, data->sg_len, DMA_FROM_DEVICE);
 
                DAT_IRQ_OFF (host,(TRE|FIFOE|MRC|TRS));
 
                mmc_request_done(host->mmc, host->mrq);
 
 
 
 
 
        }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
}
static int ocores_remove(struct platform_device *pdev)
static int ocores_remove(struct platform_device *pdev)
{
{
        struct mmc_host *mmc = platform_get_drvdata(pdev);
        struct mmc_host *mmc = platform_get_drvdata(pdev);
 
 
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);
        printk(KERN_ALERT "%s: enter\n", __FUNCTION__);

powered by: WebSVN 2.1.0

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