You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
173 lines
4.0 KiB
173 lines
4.0 KiB
/* |
|
* Copyright 2020 Broadcom |
|
* |
|
* SPDX-License-Identifier: Apache-2.0 |
|
*/ |
|
|
|
#ifndef DMA_PL330_H |
|
#define DMA_PL330_H |
|
|
|
#include <zephyr/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
|
|
|