| /* |
| * Copyright 2020 Broadcom |
| * |
| * SPDX-License-Identifier: Apache-2.0 |
| */ |
| |
| #ifndef DMA_PL330_H |
| #define DMA_PL330_H |
| |
| #include <drivers/dma.h> |
| |
| #define DT_DRV_COMPAT arm_dma_pl330 |
| /* |
| * Max burst length and max burst size for 32bit system with |
| * 128bit bus width for memory to memory data transfer |
| * |
| * Burst length is encoded in following format for pl330 |
| * b0000 = 1 data transfer |
| * b0001 = 2 data transfers |
| * b0010 = 3 data transfers |
| * . |
| * . |
| * b1111 = 16 data transfers |
| * |
| * Burst size is encoded in following format for pl330 |
| * b000 = 1 byte |
| * b001 = 2 bytes |
| * b010 = 4 bytes |
| * b011 = 8 bytes |
| * b100 = 16 bytes |
| * b101 = 32 bytes |
| * b110 = 64 bytes |
| * b111 = 128 bytes. |
| */ |
| #define MAX_BURST_LEN 0xf /* 16byte data */ |
| #define MAX_BURST_SIZE_LOG2 4 |
| |
| /* |
| * PL330 works only on 4GB boundary. |
| * PL330 has 32bit registers for source and destination addresses |
| */ |
| #define PL330_MAX_OFFSET 0x100000000 |
| |
| /* PL330 supports max 16MB dma based on AXI bus size */ |
| #define PL330_MAX_DMA_SIZE 0x1000000 |
| |
| /* Maximum possible values for PL330 ucode loop counters */ |
| #define PL330_LOOP_COUNTER0_MAX 0x100 |
| #define PL330_LOOP_COUNTER1_MAX 0x100 |
| |
| #define MAX_DMA_CHANNELS DT_INST_PROP(0, dma_channels) |
| |
| #define DMAC_PL330_CS0 0x100 |
| #define DMAC_PL330_DBGSTATUS 0xd00 |
| #define DMAC_PL330_DBGCMD 0xd04 |
| #define DMAC_PL330_DBGINST0 0xd08 |
| #define DMAC_PL330_DBGINST1 0xd0c |
| |
| /* |
| * TIMEOUT value of 100000us is kept to cover all possible data |
| * transfer sizes, with lesser time out value(10us) DMA channel |
| * appears to be busy on FPGA/Emul environment. Ideally 100000us |
| * timeout value should never hit. |
| */ |
| #define DMA_TIMEOUT_US 100000 |
| |
| #define CH_STATUS_MASK 0xf |
| #define DATA_MASK 0xf |
| |
| #define DMA_INTSR1_SHIFT 24 |
| #define DMA_INTSR0_SHIFT 16 |
| #define DMA_INTSR0 0xa0 |
| #define DMA_SECURE_SHIFT 17 |
| #define DMA_CH_SHIFT 8 |
| |
| #define CONTROL_OFFSET 0x4 |
| #define HIGHER_32_ADDR_MASK 0x0f |
| #define DST_ADDR_SHIFT 0x4 |
| |
| #define MICROCODE_SIZE_MAX 0x400 |
| #define TOTAL_MICROCODE_SIZE (MAX_DMA_CHANNELS * MICROCODE_SIZE_MAX) |
| #define GET_MAX_DMA_SIZE(byte_width, burst_len) \ |
| (PL330_LOOP_COUNTER0_MAX * PL330_LOOP_COUNTER1_MAX * \ |
| (byte_width) * ((burst_len) + 1)) |
| |
| #define CC_SRCINC_SHIFT 0 |
| #define CC_DSTINC_SHIFT 14 |
| #define CC_SRCPRI_SHIFT 8 |
| #define CC_DSTPRI_SHIFT 22 |
| #define CC_DSTNS_SHIFT 23 |
| #define CC_SRCBRSTLEN_SHIFT 4 |
| #define CC_DSTBRSTLEN_SHIFT 18 |
| #define CC_SRCBRSTSIZE_SHIFT 1 |
| #define CC_DSTBRSTSIZE_SHIFT 15 |
| #define CC_SRCCCTRL_SHIFT 11 |
| #define CC_SRCCCTRL_MASK 0x7 |
| #define CC_DSTCCTRL_SHIFT 25 |
| #define CC_DRCCCTRL_MASK 0x7 |
| #define CC_SWAP_SHIFT 28 |
| #define SRC_PRI_NONSEC_VALUE 0x2 |
| #define SRC_PRI_SEC_VALUE 0x0 |
| |
| #define OP_DMA_MOV 0xbc |
| #define OP_DMA_LOOP_COUNT1 0x22 |
| #define OP_DMA_LOOP 0x20 |
| #define OP_DMA_LD 0x4 |
| #define OP_DMA_ST 0x8 |
| #define OP_DMA_SEV 0x34 |
| #define OP_DMA_END 0x00 |
| #define OP_DMA_LP_BK_JMP1 0x38 |
| #define OP_DMA_LP_BK_JMP2 0x3c |
| #define SZ_CMD_DMAMOV 0x6 |
| |
| enum dmamov_type { |
| /* Source Address Register */ |
| SAR = 0, |
| /* Channel Control Register */ |
| CCR, |
| /* Destination Address Register */ |
| DAR, |
| }; |
| |
| /* Channel specific private data */ |
| struct dma_pl330_ch_internal { |
| uint64_t src_addr; |
| uint64_t dst_addr; |
| int src_burst_sz; |
| uint32_t src_burst_len; |
| int dst_burst_sz; |
| uint32_t dst_burst_len; |
| uint32_t trans_size; |
| uint32_t dst_id; |
| uint32_t src_id; |
| uint32_t perip_type; |
| uint32_t breq_only; |
| uint32_t src_cache_ctrl; |
| uint32_t dst_cache_ctrl; |
| uint32_t dst_inc; |
| uint32_t src_inc; |
| int nonsec_mode; |
| }; |
| |
| struct dma_pl330_ch_config { |
| /* Channel configuration details */ |
| uint64_t src_addr; |
| enum dma_addr_adj src_addr_adj; |
| uint64_t dst_addr; |
| enum dma_addr_adj dst_addr_adj; |
| enum dma_channel_direction direction; |
| uint32_t trans_size; |
| void *user_data; |
| dma_callback_t dma_callback; |
| mem_addr_t dma_exec_addr; |
| struct k_mutex ch_mutex; |
| int channel_active; |
| |
| /* Channel specific private data */ |
| struct dma_pl330_ch_internal internal; |
| }; |
| |
| struct dma_pl330_config { |
| mem_addr_t mcode_base; |
| mem_addr_t reg_base; |
| #ifdef CONFIG_DMA_64BIT |
| mem_addr_t control_reg_base; |
| #endif |
| }; |
| |
| struct dma_pl330_dev_data { |
| struct dma_pl330_ch_config channels[MAX_DMA_CHANNELS]; |
| }; |
| |
| #endif |