Hi,
after a long time working with SPI Slave experiments and many help from Freescale and DENX people i got a spi slave running with DMA but if i got an commuication error between SPI host and Slave the DMA transfer times out and i can not reset the spi or dma channel can anyone help me about this.
I have tried reset dma , reset spi block.. but nothing helps
code snipped from mxs_spi.c:
ss->pdesc->cmd.cmd.bits.bytes = len;
ss->pdesc->cmd.cmd.bits.pio_words = 1;
ss->pdesc->cmd.cmd.bits.wait4end = 1;
ss->pdesc->cmd.cmd.bits.dec_sem = 1;
ss->pdesc->cmd.cmd.bits.irq = 1;
//ss->pdesc->cmd.cmd.bits.chain = 1; // hello TF
ss->pdesc->cmd.cmd.bits.command = write ? DMA_READ : DMA_WRITE;
ss->pdesc->cmd.address = spi_buf_dma;
ss->pdesc->cmd.pio_words[0] = c0;
mxs_dma_desc_append(ss->dma, ss->pdesc);
mxs_dma_reset(ss->dma);
mxs_dma_ack_irq(ss->dma);
mxs_dma_enable_irq(ss->dma, 1);
init_completion(&ss->done);
mxs_dma_enable(ss->dma);
//wait_for_completion(&ss->done);
retw = wait_for_completion_timeout(&ss->done,500); // hello TF 5s
printk(" retw = %x\n",retw);
// fixme after a timeout we have to reset kernel dont know why
if(retw != 0){ // hello TF we have got a value
count = 10000;
while ((__raw_readl(ss->regs + HW_SSP_CTRL0) & BM_SSP_CTRL0_RUN)
&& count--)
continue;
if (count <= 0) {
printk(KERN_ERR "%c: timeout on line %s:%d\n",
write ? 'W' : 'C', __func__, __LINE__);
status = -ETIMEDOUT;
}
if (!dma_buf)
dma_unmap_single(ss->master_dev, spi_buf_dma, len, dir);
printk("Status on ok = %x\n",__raw_readl(ss->regs + HW_SSP_STATUS));
}else{
printk(KERN_ERR "%c: tom timeout on line %s:%d\n",
write ? 'W' : 'C', __func__, __LINE__);
status = -ETIMEDOUT;
tryed out some of this but without any success
printk("Status = %x\n",__raw_readl(ss->regs + HW_SSP_STATUS));
mxs_dma_disable(ss->dma);
mxs_dma_reset(ss->dma);
//mxs_dma_ack_irq(ss->dma);
//mxs_dma_enable_irq(ss->dma, 1);
//mxs_reset_block((void __iomem *)ss->regs + HW_SSP_CTRL0, 0);
printk("Status = %x\n",__raw_readl(ss->regs + HW_SSP_STATUS));
__raw_writel(BM_SSP_CTRL1_DMA_ENABLE, ss->regs + HW_SSP_CTRL1_CLR);
printk("Status = %x\n",__raw_readl(ss->regs + HW_SSP_STATUS));
the SSP_Status Register returns 0xE0200020 maybe anyone can interpret it dont know how bit 21 can be resetet (DMASENSE) i think this is the problem
during a normal operation without a timeout SSP Status returns 0xE0040020
thanks for help
Thomas