#include <asm/dma.h>
#include <asm/portmux.h>
#include <asm/bfin5xx_spi.h>
+#include <asm/cacheflush.h>
#define DRV_NAME "bfin-spi"
#define DRV_AUTHOR "Bryan Wu, Luke Yang"
if ((sclk % (2 * speed_hz)) > 0)
spi_baud++;
+ if (spi_baud < MIN_SPI_BAUD_VAL)
+ spi_baud = MIN_SPI_BAUD_VAL;
+
return spi_baud;
}
width, transfer->len);
/*
- * Try to map dma buffer and do a dma transfer if
- * successful use different way to r/w according to
- * drv_data->cur_chip->enable_dma
+ * Try to map dma buffer and do a dma transfer. If successful use,
+ * different way to r/w according to the enable_dma settings and if
+ * we are not doing a full duplex transfer (since the hardware does
+ * not support full duplex DMA transfers).
*/
if (!full_duplex && drv_data->cur_chip->enable_dma
&& drv_data->len > 6) {
/* set transfer mode, and enable SPI */
dev_dbg(&drv_data->pdev->dev, "doing DMA in.\n");
+ /* invalidate caches, if needed */
+ if (bfin_addr_dcachable((unsigned long) drv_data->rx))
+ invalidate_dcache_range((unsigned long) drv_data->rx,
+ (unsigned long) (drv_data->rx +
+ drv_data->len_in_bytes));
+
/* clear tx reg soformer data is not shifted out */
write_TDBR(drv_data, 0xFFFF);
} else if (drv_data->tx != NULL) {
dev_dbg(&drv_data->pdev->dev, "doing DMA out.\n");
+ /* flush caches, if needed */
+ if (bfin_addr_dcachable((unsigned long) drv_data->tx))
+ flush_dcache_range((unsigned long) drv_data->tx,
+ (unsigned long) (drv_data->tx +
+ drv_data->len_in_bytes));
+
/* start dma */
dma_enable_irq(drv_data->dma_channel);
dma_config = (RESTART | dma_width | DI_EN);
message->state = ERROR_STATE;
} else {
/* Update total byte transfered */
- message->actual_length += drv_data->len;
+ message->actual_length += drv_data->len_in_bytes;
/* Move to next transfer of this msg */
message->state = next_transfer(drv_data);