4 #include <arch/cache.h>
11 #include <soc/addressmap.h>
17 #if defined(CONFIG_DEBUG_SPI) && CONFIG_DEBUG_SPI
18 # define DEBUG_SPI(x,...) printk(BIOS_DEBUG, "TEGRA_SPI: " x)
20 # define DEBUG_SPI(x,...)
27 #define SPI_PACKET_SIZE_BYTES 1
28 #define SPI_MAX_TRANSFER_BYTES_FIFO (64 * SPI_PACKET_SIZE_BYTES)
29 #define SPI_MAX_TRANSFER_BYTES_DMA (65535 * SPI_PACKET_SIZE_BYTES)
36 #define SPI_FIFO_XFER_TIMEOUT_US 1000
39 #define SPI_CMD1_GO (1 << 31)
40 #define SPI_CMD1_M_S (1 << 30)
41 #define SPI_CMD1_MODE_MASK 0x3
42 #define SPI_CMD1_MODE_SHIFT 28
43 #define SPI_CMD1_CS_SEL_MASK 0x3
44 #define SPI_CMD1_CS_SEL_SHIFT 26
45 #define SPI_CMD1_CS_POL_INACTIVE3 (1 << 25)
46 #define SPI_CMD1_CS_POL_INACTIVE2 (1 << 24)
47 #define SPI_CMD1_CS_POL_INACTIVE1 (1 << 23)
48 #define SPI_CMD1_CS_POL_INACTIVE0 (1 << 22)
49 #define SPI_CMD1_CS_SW_HW (1 << 21)
50 #define SPI_CMD1_CS_SW_VAL (1 << 20)
51 #define SPI_CMD1_IDLE_SDA_MASK 0x3
52 #define SPI_CMD1_IDLE_SDA_SHIFT 18
53 #define SPI_CMD1_BIDIR (1 << 17)
54 #define SPI_CMD1_LSBI_FE (1 << 16)
55 #define SPI_CMD1_LSBY_FE (1 << 15)
56 #define SPI_CMD1_BOTH_EN_BIT (1 << 14)
57 #define SPI_CMD1_BOTH_EN_BYTE (1 << 13)
58 #define SPI_CMD1_RX_EN (1 << 12)
59 #define SPI_CMD1_TX_EN (1 << 11)
60 #define SPI_CMD1_PACKED (1 << 5)
61 #define SPI_CMD1_BIT_LEN_MASK 0x1f
62 #define SPI_CMD1_BIT_LEN_SHIFT 0
65 #define SPI_CMD2_TX_CLK_TAP_DELAY (1 << 6)
66 #define SPI_CMD2_TX_CLK_TAP_DELAY_MASK (0x3F << 6)
67 #define SPI_CMD2_RX_CLK_TAP_DELAY (1 << 0)
68 #define SPI_CMD2_RX_CLK_TAP_DELAY_MASK (0x3F << 0)
71 #define SPI_STATUS_RDY (1 << 30)
72 #define SPI_STATUS_SLV_IDLE_COUNT_MASK 0xff
73 #define SPI_STATUS_SLV_IDLE_COUNT_SHIFT 16
74 #define SPI_STATUS_BLOCK_COUNT 0xffff
75 #define SPI_STATUS_BLOCK_COUNT_SHIFT 0
78 #define SPI_FIFO_STATUS_CS_INACTIVE (1 << 31)
79 #define SPI_FIFO_STATUS_FRAME_END (1 << 30)
80 #define SPI_FIFO_STATUS_RX_FIFO_FULL_COUNT_MASK 0x7f
81 #define SPI_FIFO_STATUS_RX_FIFO_FULL_COUNT_SHIFT 23
82 #define SPI_FIFO_STATUS_TX_FIFO_EMPTY_COUNT_MASK 0x7f
83 #define SPI_FIFO_STATUS_TX_FIFO_EMPTY_COUNT_SHIFT 16
84 #define SPI_FIFO_STATUS_RX_FIFO_FLUSH (1 << 15)
85 #define SPI_FIFO_STATUS_TX_FIFO_FLUSH (1 << 14)
86 #define SPI_FIFO_STATUS_ERR (1 << 8)
87 #define SPI_FIFO_STATUS_TX_FIFO_OVF (1 << 7)
88 #define SPI_FIFO_STATUS_TX_FIFO_UNR (1 << 6)
89 #define SPI_FIFO_STATUS_RX_FIFO_OVF (1 << 5)
90 #define SPI_FIFO_STATUS_RX_FIFO_UNR (1 << 4)
91 #define SPI_FIFO_STATUS_TX_FIFO_FULL (1 << 3)
92 #define SPI_FIFO_STATUS_TX_FIFO_EMPTY (1 << 2)
93 #define SPI_FIFO_STATUS_RX_FIFO_FULL (1 << 1)
94 #define SPI_FIFO_STATUS_RX_FIFO_EMPTY (1 << 0)
97 #define SPI_DMA_CTL_DMA (1 << 31)
98 #define SPI_DMA_CTL_CONT (1 << 30)
99 #define SPI_DMA_CTL_IE_RX (1 << 29)
100 #define SPI_DMA_CTL_IE_TX (1 << 28)
101 #define SPI_DMA_CTL_RX_TRIG_MASK 0x3
102 #define SPI_DMA_CTL_RX_TRIG_SHIFT 19
103 #define SPI_DMA_CTL_TX_TRIG_MASK 0x3
104 #define SPI_DMA_CTL_TX_TRIG_SHIFT 15
107 #define SPI_DMA_CTL_BLOCK_SIZE_MASK 0xffff
108 #define SPI_DMA_CTL_BLOCK_SIZE_SHIFT 0
125 .slave = { .bus = 2, },
130 .slave = { .bus = 3, },
135 .slave = { .bus = 4, },
140 .slave = { .bus = 5, },
145 .slave = { .bus = 6, },
150 .slave = { .bus = 7, },
262 "\tdma_blk: 0x%08x\n"
263 "\tcommand1: 0x%08x\n"
264 "\tdma_ctl: 0x%08x\n"
265 "\ttrans_status: 0x%08x\n",
276 "\tahb_ptr: 0x%08x\n"
277 "\tapb_ptr: 0x%08x\n"
278 "\tahb_seq: 0x%08x\n"
279 "\tapb_seq: 0x%08x\n"
283 "\tdma_byte_sta: 0x%08x\n"
284 "\tword_transfer: 0x%08x\n",
364 unsigned int to_fifo = bytes;
453 unsigned int todo, wcount;
652 if (bytes < line_size) {
665 if ((align != 0) && (align != line_size)) {
678 if (bytes - align > 0) {
679 unsigned int dma_bytes = bytes - align;
735 size_t out_bytes,
void *din,
size_t in_bytes)
746 while (out_bytes || in_bytes) {
751 else if (in_bytes == 0)
754 todo =
MIN(out_bytes, in_bytes);
807 "%zu out / %zu in\n", todo, out_bytes, in_bytes);
void dcache_clean_by_mva(void const *addr, size_t len)
unsigned int dcache_line_bytes(void)
static void write32(void *addr, uint32_t val)
static uint32_t read32(const void *addr)
static uint8_t read8(const void *addr)
#define printk(level,...)
#define setbits32(addr, set)
#define clrsetbits32(addr, clear, set)
#define clrbits32(addr, clear)
#define BIOS_INFO
BIOS_INFO - Expected events.
#define BIOS_ERR
BIOS_ERR - System in incomplete state.
const struct spi_ctrlr_buses spi_ctrlr_bus_map[]
const size_t spi_ctrlr_bus_map_count
struct tegra_spi_channel * tegra_spi_init(unsigned int bus)
static int tegra_spi_dma_finish(struct tegra_spi_channel *spi)
#define SPI_FIFO_STATUS_RX_FIFO_UNR
#define SPI_CMD1_CS_SEL_MASK
static int xfer_setup(struct tegra_spi_channel *spi, void *buf, unsigned int bytes, enum spi_direction dir)
static struct tegra_spi_channel tegra_spi_channels[]
static void flush_fifos(struct tegra_spi_channel *spi)
#define SPI_CMD1_BIT_LEN_SHIFT
#define SPI_CMD1_CS_POL_INACTIVE0
static void spi_ctrlr_release_bus(const struct spi_slave *slave)
static void dump_spi_regs(struct tegra_spi_channel *spi)
static void clear_fifo_status(struct tegra_spi_channel *spi)
static int tegra_spi_dma_prepare(struct tegra_spi_channel *spi, unsigned int bytes, enum spi_direction dir)
#define SPI_FIFO_STATUS_RX_FIFO_FULL_COUNT_MASK
#define SPI_FIFO_STATUS_TX_FIFO_FLUSH
#define SPI_DMA_CTL_RX_TRIG_SHIFT
static void tegra_spi_wait(struct tegra_spi_channel *spi)
#define SPI_DMA_CTL_TX_TRIG_SHIFT
#define SPI_FIFO_STATUS_TX_FIFO_UNR
static void xfer_start(struct tegra_spi_channel *spi)
static void setup_dma_params(struct tegra_spi_channel *spi, struct apb_dma_channel *dma)
static int tegra_spi_pio_prepare(struct tegra_spi_channel *spi, unsigned int bytes, enum spi_direction dir)
#define SPI_FIFO_STATUS_TX_FIFO_OVF
static void dump_dma_regs(struct apb_dma_channel *dma)
#define SPI_CMD1_CS_SW_HW
static void dump_fifo_status(struct tegra_spi_channel *spi)
#define SPI_DMA_CTL_RX_TRIG_MASK
#define SPI_CMD1_BIT_LEN_MASK
#define SPI_CMD1_CS_SW_VAL
#define SPI_STATUS_BLOCK_COUNT
#define SPI_STATUS_BLOCK_COUNT_SHIFT
static u32 rx_fifo_count(struct tegra_spi_channel *spi)
#define SPI_DMA_CTL_BLOCK_SIZE_MASK
#define SPI_FIFO_STATUS_RX_FIFO_EMPTY
#define SPI_DMA_CTL_BLOCK_SIZE_SHIFT
static void tegra_spi_dma_start(struct tegra_spi_channel *spi)
static unsigned int spi_byte_count(struct tegra_spi_channel *spi)
static int fifo_error(struct tegra_spi_channel *spi)
#define SPI_FIFO_STATUS_ERR
#define SPI_FIFO_STATUS_RX_FIFO_FLUSH
static void tegra_spi_pio_start(struct tegra_spi_channel *spi)
#define SPI_CMD1_CS_SEL_SHIFT
static int spi_ctrlr_claim_bus(const struct spi_slave *slave)
static int xfer_finish(struct tegra_spi_channel *spi)
static int spi_ctrlr_xfer(const struct spi_slave *slave, const void *dout, size_t out_bytes, void *din, size_t in_bytes)
#define SPI_DMA_CTL_TX_TRIG_MASK
static struct tegra_spi_channel *const to_tegra_spi(int bus)
#define SPI_MAX_TRANSFER_BYTES_DMA
#define SPI_MAX_TRANSFER_BYTES_FIFO
#define SPI_FIFO_STATUS_RX_FIFO_OVF
static void xfer_wait(struct tegra_spi_channel *spi)
static int tegra_spi_pio_finish(struct tegra_spi_channel *spi)
#define SPI_FIFO_STATUS_RX_FIFO_FULL_COUNT_SHIFT
#define SPI_CTRLR_DEFAULT_MAX_XFER_SIZE
static struct spi_slave slave
#define dcache_clean_invalidate_by_mva(addr, len)
struct apb_dma_channel_regs * regs
const struct spi_ctrlr * ctrlr
int(* claim_bus)(const struct spi_slave *slave)
enum spi_xfer_mode xfer_mode
struct tegra_spi_regs * regs
struct apb_dma_channel * dma_in
struct apb_dma_channel * dma_out
int dma_start(struct apb_dma_channel *const channel)
int dma_stop(struct apb_dma_channel *const channel)
void dma_release(struct apb_dma_channel *const channel)
int dma_busy(struct apb_dma_channel *const channel)
struct apb_dma_channel *const dma_claim(void)
#define APB_CSR_REQ_SEL_SHIFT
#define APB_BUS_WIDTH_MASK
#define APB_BUS_WIDTH_SHIFT
#define TEGRA_DMA_ALIGN_BYTES
#define APB_CSR_REQ_SEL_MASK
#define SECURITY_EN_BIT(ch)