*/\r
\r
//#define QUICK_TRANSFER \r
-\r
#if 0\r
#define DBG printk\r
+//#define PRINT_TRANS_DATA\r
#else\r
#define DBG(x...)\r
#endif\r
}\r
#endif\r
\r
+#if defined(PRINT_TRANS_DATA)\r
+static void printk_transfer_data(unsigned char *buf, int len)\r
+{\r
+ int i = 0;\r
+ for(i=0; i<len; i++)\r
+ printk("0x%x,",*buf++);\r
+\r
+ printk("\n");\r
+\r
+}\r
+#endif\r
\r
static void spi_dump_regs(struct rk29xx_spi *dws) {\r
DBG("MRST SPI0 registers:\n");\r
\r
static int u8_writer(struct rk29xx_spi *dws)\r
{ \r
- spi_dump_regs(dws);\r
+ //spi_dump_regs(dws)\r
+#if defined(PRINT_TRANS_DATA)\r
DBG("tx: 0x%02x\n", *(u8 *)(dws->tx));\r
+#endif\r
if ((rk29xx_readw(dws, SPIM_SR) & SR_TF_FULL)\r
|| (dws->tx == dws->tx_end))\r
return 0;\r
\r
static int u8_reader(struct rk29xx_spi *dws)\r
{\r
- spi_dump_regs(dws);\r
+ //spi_dump_regs(dws);\r
while (!(rk29xx_readw(dws, SPIM_SR) & SR_RF_EMPT)\r
&& (dws->rx < dws->rx_end)) {\r
*(u8 *)(dws->rx) = rk29xx_readw(dws, SPIM_RXDR) & 0xFFU;\r
+#if defined(PRINT_TRANS_DATA)\r
DBG("rx: 0x%02x\n", *(u8 *)(dws->rx));\r
+#endif\r
++dws->rx;\r
}\r
\r
}\r
\r
static int u16_writer(struct rk29xx_spi *dws)\r
-{\r
+{ \r
+#if defined(PRINT_TRANS_DATA)\r
+ DBG("tx: 0x%04x\n", *(u16 *)(dws->tx));\r
+#endif\r
if ((rk29xx_readw(dws, SPIM_SR) & SR_TF_FULL)\r
|| (dws->tx == dws->tx_end))\r
return 0;\r
&& (dws->rx < dws->rx_end)) {\r
temp = rk29xx_readw(dws, SPIM_RXDR);\r
*(u16 *)(dws->rx) = temp;\r
- //DBG("rx: 0x%04x\n", *(u16 *)(dws->rx));\r
+#if defined(PRINT_TRANS_DATA)\r
+ DBG("rx: 0x%04x\n", *(u16 *)(dws->rx));\r
+#endif\r
dws->rx += 2;\r
}\r
\r
if (res == RK29_RES_OK)\r
dws->state &= ~RXBUSY;\r
else\r
- dev_err(&dws->master->dev, "DmaAbrtRx-%d, size: %d,res=%d\n", res, size,res);\r
+ dev_err(&dws->master->dev, "error:DmaAbrtRx-%d, size: %d,res=%d\n", res, size,res);\r
\r
- /* If the other done */\r
- //if (!(dws->state & TXBUSY))\r
- // complete(&dws->rx_completion);\r
+ //copy data from dma to transfer buf\r
+ if(dws->cur_transfer && (dws->cur_transfer->rx_buf != NULL))\r
+ {\r
+ memcpy(dws->cur_transfer->rx_buf, dws->buffer_rx_dma, dws->cur_transfer->len);\r
+ \r
+ #if defined(PRINT_TRANS_DATA)\r
+ printk("dma rx:");\r
+ printk_transfer_data(dws->cur_transfer->rx_buf, dws->cur_transfer->len);\r
+ #endif\r
+ }\r
\r
spin_unlock_irqrestore(&dws->lock, flags);\r
\r
- //DMA could not lose intterupt\r
- transfer_complete(dws);\r
+ /* If the other done */\r
+ if (!(dws->state & TXBUSY))\r
+ {\r
+ //complete(&dws->xfer_completion); \r
+ DBG("func: %s, line: %d,dma transfer complete\n", __FUNCTION__, __LINE__);\r
+ //DMA could not lose intterupt\r
+ transfer_complete(dws);\r
+ }\r
\r
}\r
\r
if (res == RK29_RES_OK)\r
dws->state &= ~TXBUSY;\r
else\r
- dev_err(&dws->master->dev, "DmaAbrtTx-%d, size: %d,res=%d \n", res, size,res);\r
-\r
- /* If the other done */\r
- //if (!(dws->state & RXBUSY)) \r
- // complete(&dws->tx_completion);\r
+ dev_err(&dws->master->dev, "error:DmaAbrtTx-%d, size: %d,res=%d \n", res, size,res);\r
\r
spin_unlock_irqrestore(&dws->lock, flags);\r
\r
- //DMA could not lose intterupt\r
- transfer_complete(dws);\r
+ /* If the other done */\r
+ if (!(dws->state & RXBUSY)) \r
+ {\r
+ //complete(&dws->xfer_completion);\r
+ \r
+ DBG("func: %s, line: %d,dma transfer complete\n", __FUNCTION__, __LINE__);\r
+ //DMA could not lose intterupt\r
+ transfer_complete(dws);\r
+ }\r
\r
}\r
\r
if(dws->cur_transfer->tx_buf)\r
{\r
memcpy(dws->buffer_tx_dma,dws->cur_transfer->tx_buf,dws->cur_transfer->len);\r
- dws->cur_transfer->tx_buf = dws->buffer_tx_dma; \r
- }\r
-\r
- if(dws->cur_transfer->rx_buf)\r
- {\r
- //memcpy(dws->buffer_rx_dma,dws->cur_transfer->rx_buf,dws->cur_transfer->len);\r
- dws->cur_transfer->rx_buf = dws->buffer_rx_dma; \r
}\r
\r
dws->cur_transfer->tx_dma = dws->tx_dma;\r
dws->dma_mapped = 0;\r
\r
/*it is important to close intterrupt*/\r
- spi_umask_intr(dws, 0);\r
+ spi_mask_intr(dws, 0xff);\r
rk29xx_writew(dws, SPIM_DMACR, 0);\r
\r
queue_work(dws->workqueue, &dws->pump_messages);\r
if (msg->complete)\r
msg->complete(msg->context);\r
\r
+ DBG("%s ok\n",__func__);\r
+\r
}\r
\r
static void int_error_stop(struct rk29xx_spi *dws, const char *msg)\r
/* Must be called inside pump_transfers() */\r
static void poll_transfer(struct rk29xx_spi *dws)\r
{\r
+#if defined(PRINT_TRANS_DATA)\r
DBG("%s\n",__func__);\r
+#endif\r
while (dws->write(dws)) {\r
wait_till_not_busy(dws);\r
dws->read(dws);\r
if (transfer->speed_hz != speed) {\r
speed = transfer->speed_hz;\r
if (speed > clk_get_rate(dws->clock_spim)) {\r
- dev_err(&dws->master->dev, "MRST SPI0: unsupported"\r
+ dev_err(&dws->master->dev, "MRST SPI0: unsupported "\r
"freq: %dHz\n", speed);\r
message->status = -EIO;\r
goto early_exit;\r
else\r
chip->tmode = SPI_TMOD_TO;\r
\r
- cr0 &= ~(0x3 << SPI_MODE_OFFSET);\r
+ cr0 &= ~(0x3 << SPI_MODE_OFFSET); \r
+ cr0 &= ~(0x3 << SPI_TMOD_OFFSET);\r
cr0 |= (chip->tmode << SPI_TMOD_OFFSET);\r
} \r
\r
* 2. clk_div is changed\r
* 3. control value changes\r
*/\r
- if (rk29xx_readw(dws, SPIM_CTRLR0) != cr0 || cs_change || clk_div || imask) {\r
+ if ((rk29xx_readl(dws, SPIM_CTRLR0) != cr0) || cs_change || clk_div || imask) {\r
spi_enable_chip(dws, 0);\r
- if (rk29xx_readw(dws, SPIM_CTRLR0) != cr0)\r
- rk29xx_writew(dws, SPIM_CTRLR0, cr0);\r
+ if (rk29xx_readl(dws, SPIM_CTRLR0) != cr0)\r
+ rk29xx_writel(dws, SPIM_CTRLR0, cr0);\r
\r
spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); \r
spi_chip_sel(dws, spi->chip_select);\r
if (transfer->speed_hz != speed) {\r
speed = transfer->speed_hz;\r
if (speed > clk_get_rate(dws->clock_spim)) {\r
- dev_err(&dws->master->dev, "MRST SPI0: unsupported"\r
+ dev_err(&dws->master->dev, "MRST SPI0: unsupported "\r
"freq: %dHz\n", speed);\r
message->status = -EIO;\r
goto err_out;\r
chip->tmode = SPI_TMOD_TO;\r
\r
cr0 &= ~(0x3 << SPI_MODE_OFFSET);\r
+ cr0 &= ~(0x3 << SPI_TMOD_OFFSET);\r
cr0 |= (chip->tmode << SPI_TMOD_OFFSET);\r
}\r
\r
* 2. clk_div is changed\r
* 3. control value changes\r
*/\r
- if (rk29xx_readw(dws, SPIM_CTRLR0) != cr0 || cs_change || clk_div) {\r
+ if ((rk29xx_readl(dws, SPIM_CTRLR0) != cr0) || cs_change || clk_div) {\r
spi_enable_chip(dws, 0);\r
- if (rk29xx_readw(dws, SPIM_CTRLR0) != cr0) {\r
- rk29xx_writew(dws, SPIM_CTRLR0, cr0);\r
+ if (rk29xx_readl(dws, SPIM_CTRLR0) != cr0) {\r
+ rk29xx_writel(dws, SPIM_CTRLR0, cr0);\r
}\r
-\r
spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); \r
spi_chip_sel(dws, spi->chip_select);\r
/* Set the interrupt mask, for poll mode just diable all int */\r
if (transfer->rx_buf != NULL) {\r
dmacr |= SPI_DMACR_RX_ENABLE;\r
rk29xx_writew(dws, SPIM_DMARDLR, 0);\r
- rk29xx_writew(dws, SPIM_CTRLR1, transfer->len-1);\r
+ rk29xx_writew(dws, SPIM_CTRLR1, transfer->len-1); \r
}\r
rk29xx_writew(dws, SPIM_DMACR, dmacr);\r
spi_enable_chip(dws, 1);\r
\r
//INIT_COMPLETION(dws->xfer_completion);\r
\r
- spi_dump_regs(dws);\r
- DBG("dws->tx_dmach: %d, dws->rx_dmach: %d, transfer->tx_dma: 0x%x\n", dws->tx_dmach, dws->rx_dmach, (unsigned int)transfer->tx_dma);\r
- if (transfer->tx_buf != NULL) {\r
- dws->state |= TXBUSY;\r
+ //spi_dump_regs(dws);\r
+ \r
+ DBG("dws->tx_dmach: %d, dws->rx_dmach: %d, dws->tx_dma: 0x%x,dws->rx_dma: 0x%x\n", dws->tx_dmach, dws->rx_dmach, (unsigned int)dws->tx_dma,(unsigned int)dws->rx_dma); \r
+ DBG("dws->buffer_tx_dma: 0x%p, dws->buffer_rx_dma: 0x%p,dws->dma_width=%d\n", dws->buffer_tx_dma, dws->buffer_rx_dma,dws->dma_width); \r
+\r
+ if (transfer->tx_buf != NULL) \r
+ dws->state |= TXBUSY; \r
+ if (transfer->rx_buf != NULL) \r
+ dws->state |= RXBUSY;\r
+\r
+ if (transfer->tx_buf != NULL) { \r
+ DBG("%s:start dma tx,dws->state=0x%x\n",__func__,dws->state);\r
+ #if defined(PRINT_TRANS_DATA)\r
+ printk("dma tx:");\r
+ printk_transfer_data(dws->buffer_tx_dma, dws->cur_transfer->len);\r
+ #endif\r
/*if (transfer->len & 0x3) {\r
burst = 1;\r
}\r
burst = 4;\r
}\r
if (rk29_dma_config(dws->tx_dmach, burst)) {*/\r
- if (rk29_dma_config(dws->tx_dmach, 1, 1)) {//there is not dma burst but bitwide, set it 1 alwayss\r
+ if (rk29_dma_config(dws->tx_dmach, dws->dma_width, 1)) {//there is not dma burst but bitwide, set it 1 alwayss\r
dev_err(&dws->master->dev, "function: %s, line: %d\n", __FUNCTION__, __LINE__);\r
goto err_out;\r
}\r
rk29_dma_ctrl(dws->tx_dmach, RK29_DMAOP_FLUSH); \r
\r
iRet = rk29_dma_enqueue(dws->tx_dmach, (void *)dws,\r
- transfer->tx_dma, transfer->len);\r
+ dws->tx_dma, transfer->len);\r
if (iRet) {\r
dev_err(&dws->master->dev, "function: %s, line: %d, iRet: %d(dws->tx_dmach: %d, transfer->tx_dma: 0x%x)\n", __FUNCTION__, __LINE__, iRet, \r
dws->tx_dmach, (unsigned int)transfer->tx_dma);\r
\r
//wait_till_not_busy(dws);\r
\r
- if (transfer->rx_buf != NULL) {\r
- dws->state |= RXBUSY;\r
- if (rk29_dma_config(dws->rx_dmach, 1, 1)) {\r
+ if (transfer->rx_buf != NULL) { \r
+ DBG("%s:start dma rx,dws->state=0x%x\n",__func__,dws->state);\r
+ if (rk29_dma_config(dws->rx_dmach, dws->dma_width, 1)) {\r
dev_err(&dws->master->dev, "function: %s, line: %d\n", __FUNCTION__, __LINE__);\r
goto err_out;\r
}\r
rk29_dma_ctrl(dws->rx_dmach, RK29_DMAOP_FLUSH); \r
\r
iRet = rk29_dma_enqueue(dws->rx_dmach, (void *)dws,\r
- transfer->rx_dma, transfer->len);\r
+ dws->rx_dma, transfer->len);\r
if (iRet) {\r
dev_err(&dws->master->dev, "function: %s, line: %d\n", __FUNCTION__, __LINE__);\r
goto err_out;\r
}\r
}\r
\r
+ //wait_till_not_busy(dws);\r
+ \r
return;\r
\r
err_out:\r
container_of(work, struct rk29xx_spi, pump_messages);\r
unsigned long flags;\r
\r
- DBG(KERN_INFO "pump_messages\n");\r
+ DBG(KERN_INFO "pump_messages,line=%d\n",__LINE__);\r
\r
/* Lock queue and check for queue work */\r
spin_lock_irqsave(&dws->lock, flags);\r
if (list_empty(&dws->queue) || dws->run == QUEUE_STOPPED) {\r
dws->busy = 0;\r
spin_unlock_irqrestore(&dws->lock, flags);\r
- mutex_unlock(&dws->dma_lock);\r
+ DBG("%s:line=%d,list_empty\n",__func__,__LINE__);\r
return;\r
}\r
\r
/* Make sure we are not already running a message */\r
if (dws->cur_msg) {\r
- spin_unlock_irqrestore(&dws->lock, flags);\r
- mutex_unlock(&dws->dma_lock);\r
+ spin_unlock_irqrestore(&dws->lock, flags); \r
+ DBG("%s:line=%d,dws->cur_msg\n",__func__,__LINE__);\r
return;\r
}\r
\r
dws->cur_chip = spi_get_ctldata(dws->cur_msg->spi);\r
dws->prev_chip = NULL; //ÿ¸öpump messageʱǿÖƸüÐÂcs dxj\r
\r
+ \r
/* Mark as busy and launch transfers */\r
tasklet_schedule(&dws->pump_transfers);\r
dws->busy = 1;\r
* 3. control value changes\r
*/\r
spi_enable_chip(dws, 0);\r
- if (rk29xx_readw(dws, SPIM_CTRLR0) != cr0)\r
- rk29xx_writew(dws, SPIM_CTRLR0, cr0);\r
+ if (rk29xx_readl(dws, SPIM_CTRLR0) != cr0)\r
+ rk29xx_writel(dws, SPIM_CTRLR0, cr0);\r
\r
DBG(KERN_INFO "clk_div: 0x%x, chip->clk_div: 0x%x\n", clk_div, chip->clk_div);\r
spi_set_clk(dws, clk_div ? clk_div : chip->clk_div); \r
dev_err(&pdev->dev, "clk_get for spi fail(%p)\n", dws->clock_spim);\r
return PTR_ERR(dws->clock_spim);\r
}\r
+\r
+ dws->pclk = clk_get(&pdev->dev, "pclk_spi");\r
+ clk_enable(dws->pclk);\r
\r
mutex_init(&dws->dma_lock);\r
\r
if (status != 0)\r
dev_err(&dws->master->dev, "rk29xx_spi_remove: workqueue will not "\r
"complete, message memory not freed\n");\r
- clk_put(dws->clock_spim);\r
+ \r
clk_disable(dws->clock_spim);\r
+ clk_put(dws->clock_spim);\r
+ clk_disable(dws->pclk);\r
+ clk_put(dws->pclk);\r
spi_enable_chip(dws, 0);\r
/* Disable clk */\r
spi_set_clk(dws, 0);\r
{\r
pdata->io_fix_leakage_bug( );\r
}\r
+ clk_disable(dws->pclk);\r
return 0;\r
}\r
\r
struct rk29xx_spi *dws = spi_master_get_devdata(master);\r
struct rk29xx_spi_platform_data *pdata = pdev->dev.platform_data;\r
int ret;\r
- \r
+\r
+ clk_enable(dws->pclk);\r
clk_enable(dws->clock_spim); \r
spi_hw_init(dws);\r
ret = start_queue(dws);\r