// SPDX-License-Identifier: GPL-2.0
/*
* Copyright (C) 2013-2014 Renesas Electronics Europe Ltd.
* Author: Guennadi Liakhovetski <g.liakhovetski@gmx.de>
*/
#include <linux/bitmap.h>
#include <linux/bitops.h>
#include <linux/clk.h>
#include <linux/dma-mapping.h>
#include <linux/dmaengine.h>
#include <linux/err.h>
#include <linux/interrupt.h>
#include <linux/io.h>
#include <linux/log2.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/of_device.h>
#include <linux/of_dma.h>
#include <linux/platform_device.h>
#include <linux/slab.h>
#include <dt-bindings/dma/nbpfaxi.h>
#include "dmaengine.h"
#define NBPF_REG_CHAN_OFFSET 0
#define NBPF_REG_CHAN_SIZE 0x40
/* Channel Current Transaction Byte register */
#define NBPF_CHAN_CUR_TR_BYTE 0x20
/* Channel Status register */
#define NBPF_CHAN_STAT 0x24
#define NBPF_CHAN_STAT_EN 1
#define NBPF_CHAN_STAT_TACT 4
#define NBPF_CHAN_STAT_ERR 0x10
#define NBPF_CHAN_STAT_END 0x20
#define NBPF_CHAN_STAT_TC 0x40
#define NBPF_CHAN_STAT_DER 0x400
/* Channel Control register */
#define NBPF_CHAN_CTRL 0x28
#define NBPF_CHAN_CTRL_SETEN 1
#define NBPF_CHAN_CTRL_CLREN 2
#define NBPF_CHAN_CTRL_STG 4
#define NBPF_CHAN_CTRL_SWRST 8
#define NBPF_CHAN_CTRL_CLRRQ 0x10
#define NBPF_CHAN_CTRL_CLREND 0x20
#define NBPF_CHAN_CTRL_CLRTC 0x40
#define NBPF_CHAN_CTRL_SETSUS 0x100
#define NBPF_CHAN_CTRL_CLRSUS 0x200
/* Channel Configuration register */
#define NBPF_CHAN_CFG 0x2c
#define NBPF_CHAN_CFG_SEL 7 /* terminal SELect: 0..7 */
#define NBPF_CHAN_CFG_REQD 8 /* REQuest Direction: DMAREQ is 0: input, 1: output */
#define NBPF_CHAN_CFG_LOEN 0x10 /* LOw ENable: low DMA request line is: 0: inactive, 1: active */
#define NBPF_CHAN_CFG_HIEN 0x20 /* HIgh ENable: high DMA request line is: 0: inactive, 1: active */
#define NBPF_CHAN_CFG_LVL 0x40 /* LeVeL: DMA request line is sensed as 0: edge, 1: level */
#define NBPF_CHAN_CFG_AM 0x700 /* ACK Mode: 0: Pulse mode, 1: Level mode, b'1x: Bus Cycle */
#define NBPF_CHAN_CFG_SDS 0xf000 /* Source Data Size: 0: 8 bits,... , 7: 1024 bits */
#define NBPF_CHAN_CFG_DDS 0xf0000 /* Destination Data Size: as above */
#define NBPF_CHAN_CFG_SAD 0x100000 /* Source ADdress counting: 0: increment, 1: fixed */
#define NBPF_CHAN_CFG_DAD 0x200000 /* Destination ADdress counting: 0: increment, 1: fixed */
#define NBPF_CHAN_CFG_TM 0x400000 /* Transfer Mode: 0: single, 1: block TM */
#define NBPF_CHAN_CFG_DEM 0x1000000 /* DMAEND interrupt Mask */
#define NBPF_CHAN_CFG_TCM 0x2000000 /* DMATCO interrupt Mask */
#define NBPF_CHAN_CFG_SBE 0x8000000 /* Sweep Buffer Enable */
#define NBPF_CHAN_CFG_RSEL 0x10000000 /* RM: Register Set sELect */
#define NBPF_CHAN_CFG_RSW 0x20000000 /* RM: Register Select sWitch */
#define NBPF_CHAN_CFG_REN 0x40000000 /* RM: Register Set Enable */
#define NBPF_CHAN_CFG_DMS 0x80000000 /* 0: register mode (RM), 1: link mode (LM) */
#define NBPF_CHAN_NXLA 0x38
#define NBPF_CHAN_CRLA 0x3c
/* Link Header field */
#define NBPF_HEADER_LV 1
#define NBPF_HEADER_LE 2
#define NBPF_HEADER_WBD 4
#define NBPF_HEADER_DIM 8
#define NBPF_CTRL 0x300
#define NBPF_CTRL_PR 1 /* 0: fixed priority, 1: round robin */
#define NBPF_CTRL_LVINT 2 /* DMAEND and DMAERR signalling: 0: pulse, 1: level */
#define NBPF_DSTAT_ER 0x314
#define NBPF_DSTAT_END 0x318
#define NBPF_DMA_BUSWIDTHS \
(BIT(DMA_SLAVE_BUSWIDTH_UNDEFINED) | \
BIT(DMA_SLAVE_BUSWIDTH_1_BYTE) | \
BIT(DMA_SLAVE_BUSWIDTH_2_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_4_BYTES) | \
BIT(DMA_SLAVE_BUSWIDTH_8_BYTES))
struct nbpf_config {
int num_channels;
int buffer_size;
};
/*
* We've got 3 types of objects, used to describe DMA transfers:
* 1. high-level descriptor, containing a struct dma_async_tx_descriptor object
* in it, used to communicate with the user
* 2. hardware DMA link descriptors, that we pass to DMAC for DMA transfer
* queuing, these must be DMAable, using either the streaming DMA API or
* allocated from coherent memory - one per SG segment
* 3. one per SG segment descriptors, used to manage HW link descriptors from
* (2). They do not have to be DMAable. They can either be (a) allocated
* together with link descriptors as mixed (DMA / CPU) objects, or (b)
* separately. Even if allocated separately it would be best to link them
* to link descriptors once during channel resource allocation and always
* use them as a single object.
* Therefore for both cases (a) and (b) at run-time objects (2) and (3) shall be
* treated as a single SG segment descriptor.
*/
struct nbpf_link_reg {
u32 header;
u32 src_addr;
u32 dst_addr;
u32 transaction_size;
u32 config;
u32 interval;
u32 extension;
u32 next;
} __packed;
struct nbpf_device;
struct nbpf_channel;
struct nbpf_desc;
struct nbpf_link_desc {
struct nbpf_link_reg *hwdesc;
dma_addr_t hwdesc_dma_addr;
struct nbpf_desc *desc;
struct list_head node;
};
/**
* struct nbpf_desc - DMA transfer descriptor
* @async_tx: dmaengine object
* @user_wait: waiting for a user ack
* @length: total transfer length
* @chan: associated DMAC channel
* @sg: list of hardware descriptors, represented by struct nbpf_link_desc
* @node: member in channel descriptor lists
*/
struct nbpf_desc {
struct dma_async_tx_descriptor async_tx;
bool user_wait;
size_t length;
struct nbpf_channel *chan;
struct list_head sg;
struct list_head node;
};
/* Take a wild guess: allocate 4 segments per descriptor */
#define NBPF_SEGMENTS_PER_DESC 4
#define NBPF_DESCS_PER_PAGE ((PAGE_SIZE - sizeof(struct list_head)) / \
(sizeof(struct nbpf_desc) + \
NBPF_SEGMENTS_PER_DESC * \
(sizeof(struct nbpf_link_desc) + sizeof(struct nbpf_link_reg))))
#define NBPF_SEGMENTS_PER_PAGE (NBPF_SEGMENTS_PER_DESC * NBPF_DESCS_PER_PAGE)
struct nbpf_desc_page {
struct list_head node;
struct nbpf_desc desc[NBPF_DESCS_PER_PAGE];
struct nbpf_link_desc ldesc[NBPF_SEGMENTS_PER_PAGE];
struct nbpf_link_reg hwdesc[NBPF_SEGMENTS_PER_PAGE];
};
/**
* struct nbpf_channel - one DMAC channel
* @dma_chan: standard dmaengine channel object
* @tasklet: channel specific tasklet used for callbacks
* @base: register address base
* @nbpf: DMAC
* @name: IRQ name
* @irq: IRQ number
* @slave_src_addr: source address for slave DMA
* @slave_src_width: source slave data size in bytes
* @slave_src_burst: maximum source slave burst size in bytes
* @slave_dst_addr: destination address for slave DMA
* @slave_dst_width: destination slave data size in bytes
* @slave_dst_burst: maximum destination slave burst size in bytes
* @terminal: DMA terminal, assigned to this channel
* @dmarq_cfg: DMA request line configuration - high / low, edge / level for NBPF_CHAN_CFG
* @flags: configuration flags from DT
* @lock: protect descriptor lists
* @free_links: list of free link descriptors
* @free: list of free descriptors
* @queued: list of queued descriptors
* @active: list of descriptors, scheduled for processing
* @done: list of completed descriptors, waiting post-processing
* @desc_page: list of additionally allocated descriptor pages - if any
* @running: linked descriptor of running transaction
* @paused:
|