URL
https://opencores.org/ocsvn/test_project/test_project/trunk
Subversion Repositories test_project
Compare Revisions
- This comparison shows the changes necessary to convert path
/
- from Rev 68 to Rev 69
- ↔ Reverse comparison
Rev 68 → Rev 69
/test_project/trunk/linux_sd_driver/drivers/mmc/host/mmc_ocores.c
38,9 → 38,8
|
struct ocores_registers |
{ |
unsigned int normal_int_status; |
unsigned int error_int_status; |
|
unsigned int normal_int_status; |
unsigned int error_int_status; |
}; |
|
struct ocores_host { |
51,7 → 50,7
unsigned int cmdat; |
unsigned int power_mode; |
struct ocores_platform_data *pdata; |
unsigned int word_cnt; |
unsigned int word_cnt; |
struct mmc_request *mrq; |
struct mmc_command *cmd; |
struct mmc_data *data; |
60,11 → 59,9
unsigned int flags; |
struct tasklet_struct finish_cmd; |
struct { |
unsigned int normal_int_status; |
unsigned int error_int_status; |
|
} registers; |
|
unsigned int normal_int_status; |
unsigned int error_int_status; |
} registers; |
}; |
|
struct ocores_host *oc_host; |
80,33 → 77,32
} |
|
static inline void CMD_IRQ_OFF(struct ocores_host *host, u32 mask) |
{ |
{ |
u32 val = readl(host->base + SD_NOMAL_INT_SIGNAL_ENABLE); |
val &= ~mask; |
writel (val, host->base + SD_NOMAL_INT_SIGNAL_ENABLE); |
|
} |
|
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); |
host->cmd = cmd; |
|
//Set up command |
|
//Set up command |
cmd_arg = cmd->arg; |
cmd_command |= cmd->opcode << 8; |
|
|
switch (mmc_resp_type(cmd)) { |
case MMC_RSP_NONE: |
cmd_command |= MMCOC_RSP_NONE; |
cmd_command |= MMCOC_RSP_NONE; |
break; |
case MMC_RSP_R1: |
cmd_command |= MMCOC_RSP_48; |
cmd_command |= MMCOC_RSP_48; |
break; |
case MMC_RSP_R1B: |
cmd_command |= MMCOC_RSP_48; |
117,51 → 113,46
case MMC_RSP_R3: |
cmd_command |= MMCOC_RSP_48; |
break; |
|
|
default: |
printk(KERN_INFO "mmc_ocores: unhandled response type %02x\n", |
mmc_resp_type(cmd)); |
} |
|
|
if ( mmc_resp_type(cmd) == MMC_RSP_CRC ) |
cmd_command |= CRCE; |
cmd_command |= CRCE; |
if ( mmc_resp_type(cmd) == MMC_RSP_OPCODE ) |
cmd_command |= CICE; |
|
|
|
cmd_command |= CICE; |
|
|
printk(KERN_ALERT "%s: cmd_arg = %08x\n", __FUNCTION__, cmd_arg); |
printk(KERN_ALERT "%s: cmd_command = %08x\n", __FUNCTION__, cmd_command); |
|
|
CMD_IRQ_ON (host,ECC); |
writel(cmd_command, host->base + SD_COMMAND); |
wmb(); |
writel(cmd_arg, host->base + SD_ARG); |
|
|
|
|
|
|
|
} |
|
static void ocores_process_next(struct ocores_host *host) |
{ |
if (!(host->flags & FL_SENT_COMMAND)) { |
host->flags |= FL_SENT_COMMAND; |
ocores_start_cmd(host, host->mrq->cmd); |
ocores_start_cmd(host, host->mrq->cmd); |
} |
else if ((!(host->flags & FL_SENT_STOP)) && host->mrq->stop) { |
host->flags |= FL_SENT_STOP; |
ocores_start_cmd(host, host->mrq->stop); |
} |
|
} |
|
static void ocores_request(struct mmc_host *mmc, struct mmc_request *mrq) |
{ |
struct ocores_host *host = mmc_priv(mmc); |
|
unsigned int cmdr, mr; |
|
|
//unsigned int cmdr, mr; |
|
printk(KERN_ALERT "%s: mrq->cmd->opcode = %08x\n", __FUNCTION__, mrq->cmd->opcode); |
printk(KERN_ALERT "%s: mrq->cmd->arg = %08x\n", __FUNCTION__, mrq->cmd->arg); |
|
169,11 → 160,10
|
host->mrq = mrq; |
host->flags = 0; |
|
ocores_process_next(host); |
|
|
|
ocores_process_next(host); |
|
|
printk(KERN_ALERT "%s: exit\n", __FUNCTION__); |
} |
|
192,11 → 182,11
} |
|
static void ocores_set_ios(struct mmc_host *mmc, struct mmc_ios *ios) |
{ |
struct ocores_host *host = mmc_priv(mmc); |
{ |
struct ocores_host *host = mmc_priv(mmc); |
int clk_div, cmd_timeout; |
/* struct ocores_host *host = mmc_priv(mmc); */ |
|
|
printk(KERN_ALERT "%s: clock = 0x%08x\n", __FUNCTION__, ios->clock); |
printk(KERN_ALERT "%s: vdd = 0x%04x\n", __FUNCTION__, ios->vdd); |
printk(KERN_ALERT "%s: bus_mode = 0x%02x\n", __FUNCTION__, ios->bus_mode); |
203,34 → 193,28
printk(KERN_ALERT "%s: power_mode = 0x%02x\n", __FUNCTION__, ios->power_mode); |
printk(KERN_ALERT "%s: bus_width = 0x%02x\n", __FUNCTION__, ios->bus_width); |
printk(KERN_ALERT "%s: timing = 0x%02x\n", __FUNCTION__, ios->timing); |
|
|
//Set clock divider and timeout registers |
printk(KERN_ALERT "%s: host->base = %p\n", __FUNCTION__, host->base); |
printk(KERN_ALERT "%s: host->base = %p\n", __FUNCTION__, host->base); |
if (ios->clock == 0) { |
//ocores_mci_write (host, SD_SOFTWARE_RST, SD_DISABLE); |
//ocores_mci_write (host, SD_SOFTWARE_RST, SD_DISABLE); |
} |
else |
{ |
{ |
writel(SD_DISABLE, host->base + SD_SOFTWARE_RST); |
clk_div = ((SYS_CLK / ios->clock)-2 )/ 2; |
cmd_timeout = ((SYS_CLK/ios->clock) * 512); |
|
|
printk(KERN_ALERT " clk_div = 0x%02x\n", clk_div); |
printk(KERN_ALERT " cmd_timeout = 0x%02x\n", cmd_timeout); |
|
|
writel (clk_div, host->base + SD_CLOCK_DIVIDER); |
writel (cmd_timeout, host->base + SD_TIMEOUT); |
|
|
|
|
|
writel(SD_ENABLE, host->base + SD_SOFTWARE_RST); |
|
} |
|
|
|
|
|
} |
|
|
237,24 → 221,25
|
static irqreturn_t ocores_irq_cmd(int irq, void *devid) |
{ |
struct ocores_host *host = oc_host; |
|
disable_irq(host->irq_cmd); |
|
//printk(KERN_ALERT "%s: IRQ START***** Normal In = %08x\n", __FUNCTION__, readl(host->base + SD_NORMAL_INT_STATUS)); |
|
host->registers.normal_int_status = readl(host->base + SD_NORMAL_INT_STATUS); |
rmb(); |
host->registers.error_int_status = readl(host->base + SD_ERROR_INT_STATUS); |
|
writel(0,host->base + SD_NORMAL_INT_STATUS); |
writel(0,host->base + SD_ERROR_INT_STATUS); |
|
printk(KERN_ALERT "%s: IRQ END***** Error In = %08x\n", __FUNCTION__, readl(host->base + SD_ERROR_INT_STATUS)); |
tasklet_schedule(&host->finish_cmd); |
CMD_IRQ_OFF (host,ECC); |
enable_irq(host->irq_cmd); |
return IRQ_HANDLED; |
struct ocores_host *host = oc_host; |
|
disable_irq(host->irq_cmd); |
|
//printk(KERN_ALERT "%s: IRQ START***** Normal In = %08x\n", __FUNCTION__, readl(host->base + SD_NORMAL_INT_STATUS)); |
|
host->registers.normal_int_status = readl(host->base + SD_NORMAL_INT_STATUS); |
rmb(); |
host->registers.error_int_status = readl(host->base + SD_ERROR_INT_STATUS); |
|
writel(0,host->base + SD_NORMAL_INT_STATUS); |
writel(0,host->base + SD_ERROR_INT_STATUS); |
|
printk(KERN_ALERT "%s: IRQ END***** Error In = %08x\n", __FUNCTION__, readl(host->base + SD_ERROR_INT_STATUS)); |
tasklet_schedule(&host->finish_cmd); |
CMD_IRQ_OFF (host,ECC); |
enable_irq(host->irq_cmd); |
|
return IRQ_HANDLED; |
} |
|
static irqreturn_t ocores_irq_dat(int irq, void *dev_id) |
261,6 → 246,7
{ |
|
} |
|
static const struct mmc_host_ops ocores_ops = { |
.request = ocores_request, |
.get_ro = ocores_get_ro, |
291,16 → 277,14
ret = -ENOMEM; |
goto out; |
} |
|
|
|
|
|
mmc->ops = &ocores_ops; |
|
|
mmc->ocr_avail = MMC_VDD_32_33 | MMC_VDD_33_34; |
mmc->caps = MMC_CAP_4_BIT_DATA; |
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_hw_segs = mmc->max_blk_count; |
312,12 → 296,12
host = mmc_priv(mmc); |
host->mmc = mmc; |
host->cmdat = 0; |
host->registers.normal_int_status =0; |
host->registers.normal_int_status =0; |
|
|
tasklet_init(&host->finish_cmd, ocores_tasklet_finish_cmd, |
(unsigned long) host); |
|
tasklet_init(&host->finish_cmd, ocores_tasklet_finish_cmd, |
(unsigned long) host); |
|
spin_lock_init(&host->lock); |
host->res = r; |
|
329,32 → 313,31
} |
host->pdata = pdev->dev.platform_data; |
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); |
printk(KERN_ALERT "%s: IRQ dat resource %x\n", __FUNCTION__, host->irq_cmd ); |
printk(KERN_ALERT "%s: RET cmd irq %x\n", __FUNCTION__, ret); |
if (ret) |
printk(KERN_ALERT "%s: IRQ dat resource %x\n", __FUNCTION__, host->irq_cmd ); |
printk(KERN_ALERT "%s: RET cmd irq %x\n", __FUNCTION__, ret); |
if (ret) |
goto out; |
disable_irq(host->irq_cmd); |
|
|
host->irq_dat = platform_get_irq_byname(pdev, "dat_irq"); |
ret = request_irq(host->irq_dat, ocores_irq_dat, IRQF_DISABLED, DRIVER_NAME, host); |
printk(KERN_ALERT "%s: IRQ dat resource %x\n", __FUNCTION__, host->irq_dat ); |
printk(KERN_ALERT "%s: RET Dat irq %x\n", __FUNCTION__, ret); |
if (ret) |
printk(KERN_ALERT "%s: IRQ dat resource %x\n", __FUNCTION__, host->irq_dat ); |
printk(KERN_ALERT "%s: RET Dat irq %x\n", __FUNCTION__, ret); |
if (ret) |
goto out; |
disable_irq(host->irq_dat); |
disable_irq(host->irq_dat); |
|
|
|
|
enable_irq(host->irq_cmd); |
enable_irq(host->irq_cmd); |
enable_irq(host->irq_dat); |
printk(KERN_ALERT "%s: host->base = %p\n", __FUNCTION__, host->base); |
printk(KERN_ALERT "%s: SD_BLOCK = %08x\n", __FUNCTION__, readl(host->base + SD_BLOCK)); |
printk(KERN_ALERT "%s: host->pdata->ocr_mask = %08x\n", __FUNCTION__, host->pdata->ocr_mask); |
oc_host=host; |
oc_host=host; |
mmc_add_host(mmc); |
|
printk(KERN_ALERT "%s: exit\n", __FUNCTION__); |
371,6 → 354,46
return ret; |
} |
|
static void ocores_tasklet_finish_cmd(unsigned long param) |
{ |
struct ocores_host *host = (struct ocores_host *) param; |
|
printk(KERN_ALERT " TASKLET RUNNS************\n"); |
|
printk(KERN_ALERT "%s: TASKLET RUNNS****** Normal INT = %08x\n", __FUNCTION__, host->registers.normal_int_status); |
printk(KERN_ALERT "%s: TASKLET RUNNS****** Error INT = %08x\n", __FUNCTION__, host->registers.error_int_status); |
|
//Check For Transmissions errors |
if ((host->registers.normal_int_status & EI) == EI) |
{ |
printk(KERN_ALERT "TRANSMISSION ERROR DETECTED"); |
switch ( host->registers.error_int_status ) |
{ |
case (CTE): |
pr_debug("Card took too long to respond\n"); |
host->mrq->cmd->error = -ETIMEDOUT ; |
break; |
case (CCRC ): |
pr_debug(" CRC problem with the received or sent data\n"); |
host->mrq->cmd->error = -EILSEQ; |
break; |
case (CIE ): |
pr_debug("Index problem with the received or sent data\n"); |
host->mrq->cmd->error = -EILSEQ; |
break; |
} |
} |
else |
{ |
host->mrq->cmd->error = 0 ; |
host->mrq->cmd->resp[0] = readl(host->base + SD_RESP1); |
printk(KERN_ALERT " CMD RSP * = %08x\n", host->mrq->cmd->resp[0]); |
} |
|
mmc_request_done(host->mmc, host->mrq); |
|
} |
|
static int ocores_remove(struct platform_device *pdev) |
{ |
struct mmc_host *mmc = platform_get_drvdata(pdev); |
441,51 → 464,6
}, |
}; |
|
static void ocores_tasklet_finish_cmd(unsigned long param) |
{ |
struct ocores_host *host = (struct ocores_host *) param; |
|
printk(KERN_ALERT " TASKLET RUNNS************\n"); |
|
printk(KERN_ALERT "%s: TASKLET RUNNS****** Normal INT = %08x\n", __FUNCTION__, host->registers.normal_int_status); |
printk(KERN_ALERT "%s: TASKLET RUNNS****** Error INT = %08x\n", __FUNCTION__, host->registers.error_int_status); |
|
//Check For Transmissions errors |
if ((host->registers.normal_int_status & EI) == EI) |
{ |
printk(KERN_ALERT "TRANSMISSION ERROR DETECTED"); |
switch ( host->registers.error_int_status ) |
{ |
case (CTE): |
pr_debug("Card took too long to respond\n"); |
host->mrq->cmd->error = -ETIMEDOUT ; |
break; |
case (CCRC ): |
pr_debug(" CRC problem with the received or sent data\n"); |
host->mrq->cmd->error = -EILSEQ; |
break; |
case (CIE ): |
pr_debug("Index problem with the received or sent data\n"); |
host->mrq->cmd->error = -EILSEQ; |
break; |
|
|
} |
} |
else |
{ |
host->mrq->cmd->error = 0 ; |
host->mrq->cmd->resp[0] = readl(host->base + SD_RESP1); |
printk(KERN_ALERT " CMD RSP * = %08x\n", host->mrq->cmd->resp[0]); |
|
} |
|
|
mmc_request_done(host->mmc, host->mrq); |
|
|
} |
|
static int __init ocores_init(void) |
{ |
printk(KERN_ALERT "%s: registering ocores platform_driver\n", __FUNCTION__); |