/* * Copyright 2020 Broadcom * * SPDX-License-Identifier: Apache-2.0 */ #ifndef DMA_PL330_H #define DMA_PL330_H #include #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