| /* SPDX-License-Identifier: GPL-2.0-only */ |
| /* This file is part of the coreboot project. */ |
| |
| #ifndef __NVIDIA_TEGRA210_DMA_H__ |
| #define __NVIDIA_TEGRA210_DMA_H__ |
| |
| #include <stdint.h> |
| #include <soc/addressmap.h> |
| #include <types.h> |
| |
| /* |
| * The DMA engine operates on 4 bytes at a time, so make sure any data |
| * passed via DMA is aligned to avoid underrun/overrun. |
| */ |
| #define TEGRA_DMA_ALIGN_BYTES 4 |
| |
| /* |
| * Note: Many APB DMA controller registers are laid out such that each |
| * bit controls or represents the status for the corresponding channel. |
| * So we will not bother to list each individual bit in this case. |
| */ |
| #define APB_COMMAND_GEN (1 << 31) |
| |
| #define APB_CNTRL_REG_COUNT_VALUE_MASK 0xffff |
| #define APB_CNTRL_REG_COUNT_VALUE_SHIFT 0 |
| |
| /* |
| * Note: Many APB DMA controller registers are laid out such that each |
| * bit controls or represents the status for the corresponding channel. |
| * So we will not bother to list each individual bit in this case. |
| */ |
| #define APB_COMMAND_GEN (1 << 31) |
| |
| #define APB_CNTRL_REG_COUNT_VALUE_MASK 0xffff |
| #define APB_CNTRL_REG_COUNT_VALUE_SHIFT 0 |
| struct apb_dma { |
| u32 command; /* 0x00 */ |
| u32 status; /* 0x04 */ |
| u32 rsvd1[2]; |
| u32 cntrl_reg; /* 0x10 */ |
| u32 irq_sta_cpu; /* 0x14 */ |
| u32 irq_sta_cop; /* 0x18 */ |
| u32 irq_mask; /* 0x1c */ |
| u32 irq_mask_set; /* 0x20 */ |
| u32 irq_mask_clr; /* 0x24 */ |
| u32 trig_reg; /* 0x28 */ |
| u32 channel_trig_reg; /* 0x2c */ |
| u32 dma_status; /* 0x30 */ |
| u32 channel_en_reg; /* 0x34 */ |
| u32 security_reg; /* 0x38 */ |
| u32 channel_swid; /* 0x3c */ |
| u32 rsvd[1]; |
| u32 chan_wt_reg0; /* 0x44 */ |
| u32 chan_wt_reg1; /* 0x48 */ |
| u32 chan_wt_reg2; /* 0x4c */ |
| u32 chan_wr_reg3; /* 0x50 */ |
| u32 channel_swid1; /* 0x54 */ |
| } __packed; |
| check_member(apb_dma, channel_swid1, 0x54); |
| |
| /* Security enable for DMA channel */ |
| #define SECURITY_EN_BIT(ch) (1 << ch) |
| |
| /* |
| * Naming in the doc included a superfluous _CHANNEL_n_ for |
| * each entry and was left out for the sake of conciseness. |
| */ |
| #define APB_CSR_ENB (1 << 31) |
| #define APB_CSR_IE_EOC (1 << 30) |
| #define APB_CSR_HOLD (1 << 29) |
| #define APB_CSR_DIR (1 << 28) |
| #define APB_CSR_ONCE (1 << 27) |
| #define APB_CSR_FLOW (1 << 21) |
| #define APB_CSR_REQ_SEL_MASK 0x1f |
| #define APB_CSR_REQ_SEL_SHIFT 16 |
| |
| enum apbdmachan_req_sel { |
| APBDMA_SLAVE_CNTR_REQ = 0, |
| APBDMA_SLAVE_APBIF_CH0 = 1, |
| APBDMA_SLAVE_APBIF_CH1 = 2, |
| APBDMA_SLAVE_APBIF_CH2 = 3, |
| APBDMA_SLAVE_APBIF_CH3 = 4, |
| APBDMA_SLAVE_QSPI = 5, |
| APBDMA_SLAVE_APBIF_CH4 = 6, |
| APBDMA_SLAVE_APBIF_CH5 = 7, |
| APBDMA_SLAVE_UART_A = 8, |
| APBDMA_SLAVE_UART_B = 9, |
| APBDMA_SLAVE_UART_C = 10, |
| APBDMA_SLAVE_DTV = 11, |
| APBDMA_SLAVE_APBIF_CH6 = 12, |
| APBDMA_SLAVE_APBIF_CH7 = 13, |
| APBDMA_SLAVE_APBIF_CH8 = 14, |
| APBDMA_SLAVE_SL2B1 = 15, |
| APBDMA_SLAVE_SL2B2 = 16, |
| APBDMA_SLAVE_SL2B3 = 17, |
| APBDMA_SLAVE_SL2B4 = 18, |
| APBDMA_SLAVE_UART_D = 19, |
| APBDMA_SLAVE_UART_E = 20, |
| APBDMA_SLAVE_I2C = 21, |
| APBDMA_SLAVE_I2C2 = 22, |
| APBDMA_SLAVE_I2C3 = 23, |
| APBDMA_SLAVE_DVC_I2C = 24, |
| APBDMA_SLAVE_OWR = 25, |
| APBDMA_SLAVE_I2C4 = 26, |
| APBDMA_SLAVE_SL2B5 = 27, |
| APBDMA_SLAVE_SL2B6 = 28, |
| APBDMA_SLAVE_APBIF_CH9 = 29, |
| APBDMA_SLAVE_I2C6 = 30, |
| APBDMA_SLAVE_NA31 = 31, |
| }; |
| |
| #define APB_STA_BSY (1 << 31) |
| #define APB_STA_ISE_EOC (1 << 30) |
| #define APB_STA_HALT (1 << 29) |
| #define APB_STA_PING_PONG_STA (1 << 28) |
| #define APB_STA_DMA_ACTIVITY (1 << 27) |
| #define APB_STA_CHANNEL_PAUSE (1 << 26) |
| |
| #define APB_CSRE_CHANNEL_PAUSE (1 << 31) |
| #define APB_CSRE_TRIG_SEL_MASK 0x3f |
| #define APB_CSRE_TRIG_SEL_SHIFT 14 |
| |
| #define AHB_PTR_MASK (0x3fffffff) |
| #define AHB_PTR_SHIFT 2 |
| |
| #define AHB_SEQ_INTR_ENB (1 << 31) |
| #define AHB_BUS_WIDTH_MASK 0x7 |
| #define AHB_BUS_WIDTH_SHIFT 28 |
| #define AHB_DATA_SWAP (1 << 27) |
| #define AHB_BURST_MASK 0x7 |
| #define AHB_BURST_SHIFT 24 |
| #define AHB_SEQ_DBL_BUF (1 << 19) |
| #define AHB_SEQ_WRAP_MASK 0x7 |
| #define AHB_SEQ_WRAP_SHIFT 16 |
| |
| #define APB_PTR_MASK 0x3fffffff |
| #define APB_PTR_SHIFT 2 |
| |
| #define APB_BUS_WIDTH_MASK 0x7 |
| #define APB_BUS_WIDTH_SHIFT 28 |
| #define APB_DATA_SWAP (1 << 27) |
| #define APB_ADDR_WRAP_MASK 0x7 |
| #define APB_ADDR_WRAP_SHIFT 16 |
| |
| #define APB_WORD_TRANSFER_MASK 0x0fffffff |
| #define APB_WORD_TRANSFER_SHIFT 2 |
| |
| struct apb_dma_channel_regs { |
| u32 csr; /* 0x00 */ |
| u32 sta; /* 0x04 */ |
| u32 dma_byte_sta; /* 0x08 */ |
| u32 csre; /* 0x0c */ |
| u32 ahb_ptr; /* 0x10 */ |
| u32 ahb_seq; /* 0x14 */ |
| u32 apb_ptr; /* 0x18 */ |
| u32 apb_seq; /* 0x1c */ |
| u32 wcount; /* 0x20 */ |
| u32 word_transfer; /* 0x24 */ |
| } __packed; |
| check_member(apb_dma_channel_regs, word_transfer, 0x24); |
| |
| struct apb_dma_channel { |
| const int num; |
| struct apb_dma_channel_regs *regs; |
| |
| /* |
| * Basic high-level semaphore that can be used to "claim" |
| * a DMA channel e.g. by SPI, I2C, or other peripheral driver. |
| */ |
| int in_use; |
| }; |
| |
| struct apb_dma_channel * const dma_claim(void); |
| void dma_release(struct apb_dma_channel * const channel); |
| int dma_start(struct apb_dma_channel * const channel); |
| int dma_stop(struct apb_dma_channel * const channel); |
| int dma_busy(struct apb_dma_channel * const channel); |
| |
| #endif /* __NVIDIA_TEGRA210_DMA_H__ */ |