1d2912cb1SThomas Gleixner /* SPDX-License-Identifier: GPL-2.0-only */
22b49e0c5SAndy Shevchenko /*
32b49e0c5SAndy Shevchenko * Driver for the High Speed UART DMA
42b49e0c5SAndy Shevchenko *
52b49e0c5SAndy Shevchenko * Copyright (C) 2015 Intel Corporation
62b49e0c5SAndy Shevchenko *
72b49e0c5SAndy Shevchenko * Partially based on the bits found in drivers/tty/serial/mfd.c.
82b49e0c5SAndy Shevchenko */
92b49e0c5SAndy Shevchenko
102b49e0c5SAndy Shevchenko #ifndef __DMA_HSU_H__
112b49e0c5SAndy Shevchenko #define __DMA_HSU_H__
122b49e0c5SAndy Shevchenko
132c40c787SAndy Shevchenko #include <linux/bits.h>
14*9c060026SAndy Shevchenko #include <linux/container_of.h>
15*9c060026SAndy Shevchenko #include <linux/io.h>
16*9c060026SAndy Shevchenko #include <linux/types.h>
17*9c060026SAndy Shevchenko
182b49e0c5SAndy Shevchenko #include <linux/dma/hsu.h>
192b49e0c5SAndy Shevchenko
202b49e0c5SAndy Shevchenko #include "../virt-dma.h"
212b49e0c5SAndy Shevchenko
222b49e0c5SAndy Shevchenko #define HSU_CH_SR 0x00 /* channel status */
232b49e0c5SAndy Shevchenko #define HSU_CH_CR 0x04 /* channel control */
242b49e0c5SAndy Shevchenko #define HSU_CH_DCR 0x08 /* descriptor control */
252b49e0c5SAndy Shevchenko #define HSU_CH_BSR 0x10 /* FIFO buffer size */
262b49e0c5SAndy Shevchenko #define HSU_CH_MTSR 0x14 /* minimum transfer size */
272b49e0c5SAndy Shevchenko #define HSU_CH_DxSAR(x) (0x20 + 8 * (x)) /* desc start addr */
282b49e0c5SAndy Shevchenko #define HSU_CH_DxTSR(x) (0x24 + 8 * (x)) /* desc transfer size */
292b49e0c5SAndy Shevchenko #define HSU_CH_D0SAR 0x20 /* desc 0 start addr */
302b49e0c5SAndy Shevchenko #define HSU_CH_D0TSR 0x24 /* desc 0 transfer size */
312b49e0c5SAndy Shevchenko #define HSU_CH_D1SAR 0x28
322b49e0c5SAndy Shevchenko #define HSU_CH_D1TSR 0x2c
332b49e0c5SAndy Shevchenko #define HSU_CH_D2SAR 0x30
342b49e0c5SAndy Shevchenko #define HSU_CH_D2TSR 0x34
352b49e0c5SAndy Shevchenko #define HSU_CH_D3SAR 0x38
362b49e0c5SAndy Shevchenko #define HSU_CH_D3TSR 0x3c
372b49e0c5SAndy Shevchenko
382b49e0c5SAndy Shevchenko #define HSU_DMA_CHAN_NR_DESC 4
392b49e0c5SAndy Shevchenko #define HSU_DMA_CHAN_LENGTH 0x40
402b49e0c5SAndy Shevchenko
412b49e0c5SAndy Shevchenko /* Bits in HSU_CH_SR */
422b49e0c5SAndy Shevchenko #define HSU_CH_SR_DESCTO(x) BIT(8 + (x))
432c40c787SAndy Shevchenko #define HSU_CH_SR_DESCTO_ANY GENMASK(11, 8)
442b49e0c5SAndy Shevchenko #define HSU_CH_SR_CHE BIT(15)
454f4bc0abSAndy Shevchenko #define HSU_CH_SR_DESCE(x) BIT(16 + (x))
462c40c787SAndy Shevchenko #define HSU_CH_SR_DESCE_ANY GENMASK(19, 16)
472c40c787SAndy Shevchenko #define HSU_CH_SR_CDESC_ANY GENMASK(31, 30)
482b49e0c5SAndy Shevchenko
492b49e0c5SAndy Shevchenko /* Bits in HSU_CH_CR */
502b49e0c5SAndy Shevchenko #define HSU_CH_CR_CHA BIT(0)
512b49e0c5SAndy Shevchenko #define HSU_CH_CR_CHD BIT(1)
522b49e0c5SAndy Shevchenko
532b49e0c5SAndy Shevchenko /* Bits in HSU_CH_DCR */
542b49e0c5SAndy Shevchenko #define HSU_CH_DCR_DESCA(x) BIT(0 + (x))
552b49e0c5SAndy Shevchenko #define HSU_CH_DCR_CHSOD(x) BIT(8 + (x))
562b49e0c5SAndy Shevchenko #define HSU_CH_DCR_CHSOTO BIT(14)
572b49e0c5SAndy Shevchenko #define HSU_CH_DCR_CHSOE BIT(15)
582b49e0c5SAndy Shevchenko #define HSU_CH_DCR_CHDI(x) BIT(16 + (x))
592b49e0c5SAndy Shevchenko #define HSU_CH_DCR_CHEI BIT(23)
602b49e0c5SAndy Shevchenko #define HSU_CH_DCR_CHTOI(x) BIT(24 + (x))
612b49e0c5SAndy Shevchenko
6217b3cf42SAndy Shevchenko /* Bits in HSU_CH_DxTSR */
6317b3cf42SAndy Shevchenko #define HSU_CH_DxTSR_MASK GENMASK(15, 0)
6417b3cf42SAndy Shevchenko #define HSU_CH_DxTSR_TSR(x) ((x) & HSU_CH_DxTSR_MASK)
6517b3cf42SAndy Shevchenko
662b49e0c5SAndy Shevchenko struct hsu_dma_sg {
672b49e0c5SAndy Shevchenko dma_addr_t addr;
682b49e0c5SAndy Shevchenko unsigned int len;
692b49e0c5SAndy Shevchenko };
702b49e0c5SAndy Shevchenko
712b49e0c5SAndy Shevchenko struct hsu_dma_desc {
722b49e0c5SAndy Shevchenko struct virt_dma_desc vdesc;
732b49e0c5SAndy Shevchenko enum dma_transfer_direction direction;
742b49e0c5SAndy Shevchenko struct hsu_dma_sg *sg;
752b49e0c5SAndy Shevchenko unsigned int nents;
76f0579c8cSAndy Shevchenko size_t length;
772b49e0c5SAndy Shevchenko unsigned int active;
782b49e0c5SAndy Shevchenko enum dma_status status;
792b49e0c5SAndy Shevchenko };
802b49e0c5SAndy Shevchenko
to_hsu_dma_desc(struct virt_dma_desc * vdesc)812b49e0c5SAndy Shevchenko static inline struct hsu_dma_desc *to_hsu_dma_desc(struct virt_dma_desc *vdesc)
822b49e0c5SAndy Shevchenko {
832b49e0c5SAndy Shevchenko return container_of(vdesc, struct hsu_dma_desc, vdesc);
842b49e0c5SAndy Shevchenko }
852b49e0c5SAndy Shevchenko
862b49e0c5SAndy Shevchenko struct hsu_dma_chan {
872b49e0c5SAndy Shevchenko struct virt_dma_chan vchan;
882b49e0c5SAndy Shevchenko
892b49e0c5SAndy Shevchenko void __iomem *reg;
902b49e0c5SAndy Shevchenko
912b49e0c5SAndy Shevchenko /* hardware configuration */
922b49e0c5SAndy Shevchenko enum dma_transfer_direction direction;
932b49e0c5SAndy Shevchenko struct dma_slave_config config;
942b49e0c5SAndy Shevchenko
952b49e0c5SAndy Shevchenko struct hsu_dma_desc *desc;
962b49e0c5SAndy Shevchenko };
972b49e0c5SAndy Shevchenko
to_hsu_dma_chan(struct dma_chan * chan)982b49e0c5SAndy Shevchenko static inline struct hsu_dma_chan *to_hsu_dma_chan(struct dma_chan *chan)
992b49e0c5SAndy Shevchenko {
1002b49e0c5SAndy Shevchenko return container_of(chan, struct hsu_dma_chan, vchan.chan);
1012b49e0c5SAndy Shevchenko }
1022b49e0c5SAndy Shevchenko
hsu_chan_readl(struct hsu_dma_chan * hsuc,int offset)1032b49e0c5SAndy Shevchenko static inline u32 hsu_chan_readl(struct hsu_dma_chan *hsuc, int offset)
1042b49e0c5SAndy Shevchenko {
1052b49e0c5SAndy Shevchenko return readl(hsuc->reg + offset);
1062b49e0c5SAndy Shevchenko }
1072b49e0c5SAndy Shevchenko
hsu_chan_writel(struct hsu_dma_chan * hsuc,int offset,u32 value)1082b49e0c5SAndy Shevchenko static inline void hsu_chan_writel(struct hsu_dma_chan *hsuc, int offset,
1092b49e0c5SAndy Shevchenko u32 value)
1102b49e0c5SAndy Shevchenko {
1112b49e0c5SAndy Shevchenko writel(value, hsuc->reg + offset);
1122b49e0c5SAndy Shevchenko }
1132b49e0c5SAndy Shevchenko
1142b49e0c5SAndy Shevchenko struct hsu_dma {
1152b49e0c5SAndy Shevchenko struct dma_device dma;
1162b49e0c5SAndy Shevchenko
1172b49e0c5SAndy Shevchenko /* channels */
1182b49e0c5SAndy Shevchenko struct hsu_dma_chan *chan;
1194c97ad99SHeikki Krogerus unsigned short nr_channels;
1202b49e0c5SAndy Shevchenko };
1212b49e0c5SAndy Shevchenko
to_hsu_dma(struct dma_device * ddev)1222b49e0c5SAndy Shevchenko static inline struct hsu_dma *to_hsu_dma(struct dma_device *ddev)
1232b49e0c5SAndy Shevchenko {
1242b49e0c5SAndy Shevchenko return container_of(ddev, struct hsu_dma, dma);
1252b49e0c5SAndy Shevchenko }
1262b49e0c5SAndy Shevchenko
1272b49e0c5SAndy Shevchenko #endif /* __DMA_HSU_H__ */
128