162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
262306a36Sopenharmony_ci/*
362306a36Sopenharmony_ci * Driver for the High Speed UART DMA
462306a36Sopenharmony_ci *
562306a36Sopenharmony_ci * Copyright (C) 2015 Intel Corporation
662306a36Sopenharmony_ci *
762306a36Sopenharmony_ci * Partially based on the bits found in drivers/tty/serial/mfd.c.
862306a36Sopenharmony_ci */
962306a36Sopenharmony_ci
1062306a36Sopenharmony_ci#ifndef __DMA_HSU_H__
1162306a36Sopenharmony_ci#define __DMA_HSU_H__
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci#include <linux/bits.h>
1462306a36Sopenharmony_ci#include <linux/container_of.h>
1562306a36Sopenharmony_ci#include <linux/io.h>
1662306a36Sopenharmony_ci#include <linux/types.h>
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci#include <linux/dma/hsu.h>
1962306a36Sopenharmony_ci
2062306a36Sopenharmony_ci#include "../virt-dma.h"
2162306a36Sopenharmony_ci
2262306a36Sopenharmony_ci#define HSU_CH_SR		0x00			/* channel status */
2362306a36Sopenharmony_ci#define HSU_CH_CR		0x04			/* channel control */
2462306a36Sopenharmony_ci#define HSU_CH_DCR		0x08			/* descriptor control */
2562306a36Sopenharmony_ci#define HSU_CH_BSR		0x10			/* FIFO buffer size */
2662306a36Sopenharmony_ci#define HSU_CH_MTSR		0x14			/* minimum transfer size */
2762306a36Sopenharmony_ci#define HSU_CH_DxSAR(x)		(0x20 + 8 * (x))	/* desc start addr */
2862306a36Sopenharmony_ci#define HSU_CH_DxTSR(x)		(0x24 + 8 * (x))	/* desc transfer size */
2962306a36Sopenharmony_ci#define HSU_CH_D0SAR		0x20			/* desc 0 start addr */
3062306a36Sopenharmony_ci#define HSU_CH_D0TSR		0x24			/* desc 0 transfer size */
3162306a36Sopenharmony_ci#define HSU_CH_D1SAR		0x28
3262306a36Sopenharmony_ci#define HSU_CH_D1TSR		0x2c
3362306a36Sopenharmony_ci#define HSU_CH_D2SAR		0x30
3462306a36Sopenharmony_ci#define HSU_CH_D2TSR		0x34
3562306a36Sopenharmony_ci#define HSU_CH_D3SAR		0x38
3662306a36Sopenharmony_ci#define HSU_CH_D3TSR		0x3c
3762306a36Sopenharmony_ci
3862306a36Sopenharmony_ci#define HSU_DMA_CHAN_NR_DESC	4
3962306a36Sopenharmony_ci#define HSU_DMA_CHAN_LENGTH	0x40
4062306a36Sopenharmony_ci
4162306a36Sopenharmony_ci/* Bits in HSU_CH_SR */
4262306a36Sopenharmony_ci#define HSU_CH_SR_DESCTO(x)	BIT(8 + (x))
4362306a36Sopenharmony_ci#define HSU_CH_SR_DESCTO_ANY	GENMASK(11, 8)
4462306a36Sopenharmony_ci#define HSU_CH_SR_CHE		BIT(15)
4562306a36Sopenharmony_ci#define HSU_CH_SR_DESCE(x)	BIT(16 + (x))
4662306a36Sopenharmony_ci#define HSU_CH_SR_DESCE_ANY	GENMASK(19, 16)
4762306a36Sopenharmony_ci#define HSU_CH_SR_CDESC_ANY	GENMASK(31, 30)
4862306a36Sopenharmony_ci
4962306a36Sopenharmony_ci/* Bits in HSU_CH_CR */
5062306a36Sopenharmony_ci#define HSU_CH_CR_CHA		BIT(0)
5162306a36Sopenharmony_ci#define HSU_CH_CR_CHD		BIT(1)
5262306a36Sopenharmony_ci
5362306a36Sopenharmony_ci/* Bits in HSU_CH_DCR */
5462306a36Sopenharmony_ci#define HSU_CH_DCR_DESCA(x)	BIT(0 + (x))
5562306a36Sopenharmony_ci#define HSU_CH_DCR_CHSOD(x)	BIT(8 + (x))
5662306a36Sopenharmony_ci#define HSU_CH_DCR_CHSOTO	BIT(14)
5762306a36Sopenharmony_ci#define HSU_CH_DCR_CHSOE	BIT(15)
5862306a36Sopenharmony_ci#define HSU_CH_DCR_CHDI(x)	BIT(16 + (x))
5962306a36Sopenharmony_ci#define HSU_CH_DCR_CHEI		BIT(23)
6062306a36Sopenharmony_ci#define HSU_CH_DCR_CHTOI(x)	BIT(24 + (x))
6162306a36Sopenharmony_ci
6262306a36Sopenharmony_ci/* Bits in HSU_CH_DxTSR */
6362306a36Sopenharmony_ci#define HSU_CH_DxTSR_MASK	GENMASK(15, 0)
6462306a36Sopenharmony_ci#define HSU_CH_DxTSR_TSR(x)	((x) & HSU_CH_DxTSR_MASK)
6562306a36Sopenharmony_ci
6662306a36Sopenharmony_cistruct hsu_dma_sg {
6762306a36Sopenharmony_ci	dma_addr_t addr;
6862306a36Sopenharmony_ci	unsigned int len;
6962306a36Sopenharmony_ci};
7062306a36Sopenharmony_ci
7162306a36Sopenharmony_cistruct hsu_dma_desc {
7262306a36Sopenharmony_ci	struct virt_dma_desc vdesc;
7362306a36Sopenharmony_ci	enum dma_transfer_direction direction;
7462306a36Sopenharmony_ci	struct hsu_dma_sg *sg;
7562306a36Sopenharmony_ci	unsigned int nents;
7662306a36Sopenharmony_ci	size_t length;
7762306a36Sopenharmony_ci	unsigned int active;
7862306a36Sopenharmony_ci	enum dma_status status;
7962306a36Sopenharmony_ci};
8062306a36Sopenharmony_ci
8162306a36Sopenharmony_cistatic inline struct hsu_dma_desc *to_hsu_dma_desc(struct virt_dma_desc *vdesc)
8262306a36Sopenharmony_ci{
8362306a36Sopenharmony_ci	return container_of(vdesc, struct hsu_dma_desc, vdesc);
8462306a36Sopenharmony_ci}
8562306a36Sopenharmony_ci
8662306a36Sopenharmony_cistruct hsu_dma_chan {
8762306a36Sopenharmony_ci	struct virt_dma_chan vchan;
8862306a36Sopenharmony_ci
8962306a36Sopenharmony_ci	void __iomem *reg;
9062306a36Sopenharmony_ci
9162306a36Sopenharmony_ci	/* hardware configuration */
9262306a36Sopenharmony_ci	enum dma_transfer_direction direction;
9362306a36Sopenharmony_ci	struct dma_slave_config config;
9462306a36Sopenharmony_ci
9562306a36Sopenharmony_ci	struct hsu_dma_desc *desc;
9662306a36Sopenharmony_ci};
9762306a36Sopenharmony_ci
9862306a36Sopenharmony_cistatic inline struct hsu_dma_chan *to_hsu_dma_chan(struct dma_chan *chan)
9962306a36Sopenharmony_ci{
10062306a36Sopenharmony_ci	return container_of(chan, struct hsu_dma_chan, vchan.chan);
10162306a36Sopenharmony_ci}
10262306a36Sopenharmony_ci
10362306a36Sopenharmony_cistatic inline u32 hsu_chan_readl(struct hsu_dma_chan *hsuc, int offset)
10462306a36Sopenharmony_ci{
10562306a36Sopenharmony_ci	return readl(hsuc->reg + offset);
10662306a36Sopenharmony_ci}
10762306a36Sopenharmony_ci
10862306a36Sopenharmony_cistatic inline void hsu_chan_writel(struct hsu_dma_chan *hsuc, int offset,
10962306a36Sopenharmony_ci				   u32 value)
11062306a36Sopenharmony_ci{
11162306a36Sopenharmony_ci	writel(value, hsuc->reg + offset);
11262306a36Sopenharmony_ci}
11362306a36Sopenharmony_ci
11462306a36Sopenharmony_cistruct hsu_dma {
11562306a36Sopenharmony_ci	struct dma_device		dma;
11662306a36Sopenharmony_ci
11762306a36Sopenharmony_ci	/* channels */
11862306a36Sopenharmony_ci	struct hsu_dma_chan		*chan;
11962306a36Sopenharmony_ci	unsigned short			nr_channels;
12062306a36Sopenharmony_ci};
12162306a36Sopenharmony_ci
12262306a36Sopenharmony_cistatic inline struct hsu_dma *to_hsu_dma(struct dma_device *ddev)
12362306a36Sopenharmony_ci{
12462306a36Sopenharmony_ci	return container_of(ddev, struct hsu_dma, dma);
12562306a36Sopenharmony_ci}
12662306a36Sopenharmony_ci
12762306a36Sopenharmony_ci#endif /* __DMA_HSU_H__ */
128