174 lines
4.0 KiB
C
174 lines
4.0 KiB
C
/*
|
|
* 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
|