13d0407baSopenharmony_ci/* SPDX-License-Identifier: GPL-2.0 */
23d0407baSopenharmony_ci/*
33d0407baSopenharmony_ci * Copyright (C) 2018 Rockchip Electronics Co., Ltd.
43d0407baSopenharmony_ci */
53d0407baSopenharmony_ci#ifndef __SOC_ROCKCHIP_PCIE_DMA_TRX_H
63d0407baSopenharmony_ci#define __SOC_ROCKCHIP_PCIE_DMA_TRX_H
73d0407baSopenharmony_ci
83d0407baSopenharmony_ci#include <linux/debugfs.h>
93d0407baSopenharmony_ci
103d0407baSopenharmony_ci#define PCIE_DMA_TABLE_NUM		32
113d0407baSopenharmony_ci
123d0407baSopenharmony_ci#define PCIE_DMA_TRX_TYPE_NUM		3
133d0407baSopenharmony_ci
143d0407baSopenharmony_ci#define PCIE_DMA_CHN0			0x0
153d0407baSopenharmony_ci#define PCIE_DMA_CHN1			0x1
163d0407baSopenharmony_ci#define PCIE_DMA_DEFAULT_CHN		PCIE_DMA_CHN0
173d0407baSopenharmony_ci
183d0407baSopenharmony_ci#define PCIE_DMA_DATA_SND_TABLE_OFFSET		0x0
193d0407baSopenharmony_ci#define PCIE_DMA_DATA_RCV_ACK_TABLE_OFFSET	0x8
203d0407baSopenharmony_ci#define PCIE_DMA_DATA_FREE_ACK_TABLE_OFFSET	0x10
213d0407baSopenharmony_ci#define PCIE_DMA_DATA_READ_REMOTE_TABLE_OFFSET	0x18
223d0407baSopenharmony_ci
233d0407baSopenharmony_cienum dma_dir {
243d0407baSopenharmony_ci	DMA_FROM_BUS,
253d0407baSopenharmony_ci	DMA_TO_BUS,
263d0407baSopenharmony_ci};
273d0407baSopenharmony_ci
283d0407baSopenharmony_ci/**
293d0407baSopenharmony_ci * The Channel Control Register for read and write.
303d0407baSopenharmony_ci */
313d0407baSopenharmony_ciunion chan_ctrl_lo {
323d0407baSopenharmony_ci	struct {
333d0407baSopenharmony_ci		u32	cb		:1;	// 0
343d0407baSopenharmony_ci		u32	tcb		:1;	// 1
353d0407baSopenharmony_ci		u32	llp		:1;	// 2
363d0407baSopenharmony_ci		u32	lie		:1;	// 3
373d0407baSopenharmony_ci		u32	rie		:1;	// 4
383d0407baSopenharmony_ci		u32	cs		:2;	// 5:6
393d0407baSopenharmony_ci		u32	rsvd1		:1;	// 7
403d0407baSopenharmony_ci		u32	ccs		:1;	// 8
413d0407baSopenharmony_ci		u32	llen		:1;	// 9
423d0407baSopenharmony_ci		u32	b_64s		:1;	// 10
433d0407baSopenharmony_ci		u32	b_64d		:1;	// 11
443d0407baSopenharmony_ci		u32	pf		:5;	// 12:16
453d0407baSopenharmony_ci		u32	rsvd2		:7;	// 17:23
463d0407baSopenharmony_ci		u32	sn		:1;	// 24
473d0407baSopenharmony_ci		u32	ro		:1;	// 25
483d0407baSopenharmony_ci		u32	td		:1;	// 26
493d0407baSopenharmony_ci		u32	tc		:3;	// 27:29
503d0407baSopenharmony_ci		u32	at		:2;	// 30:31
513d0407baSopenharmony_ci	};
523d0407baSopenharmony_ci	u32 asdword;
533d0407baSopenharmony_ci};
543d0407baSopenharmony_ci
553d0407baSopenharmony_ci/**
563d0407baSopenharmony_ci * The Channel Control Register high part for read and write.
573d0407baSopenharmony_ci */
583d0407baSopenharmony_ciunion chan_ctrl_hi {
593d0407baSopenharmony_ci	struct {
603d0407baSopenharmony_ci		u32	vfenb		:1;	// 0
613d0407baSopenharmony_ci		u32	vfunc		:8;	// 1-8
623d0407baSopenharmony_ci		u32	rsvd0		:23;	// 9-31
633d0407baSopenharmony_ci	};
643d0407baSopenharmony_ci	u32 asdword;
653d0407baSopenharmony_ci};
663d0407baSopenharmony_ci
673d0407baSopenharmony_ci/**
683d0407baSopenharmony_ci * The Channel Weight Register.
693d0407baSopenharmony_ci */
703d0407baSopenharmony_ciunion weight {
713d0407baSopenharmony_ci	struct {
723d0407baSopenharmony_ci		u32	weight0		:5;	// 0:4
733d0407baSopenharmony_ci		u32	weight1		:5;	// 5:9
743d0407baSopenharmony_ci		u32	weight2		:5;	// 10:14
753d0407baSopenharmony_ci		u32	weight3		:5;	// 15:19
763d0407baSopenharmony_ci		u32	rsvd		:12;	// 20:31
773d0407baSopenharmony_ci	};
783d0407baSopenharmony_ci	u32 asdword;
793d0407baSopenharmony_ci};
803d0407baSopenharmony_ci
813d0407baSopenharmony_ci/**
823d0407baSopenharmony_ci * The Doorbell Register for read and write.
833d0407baSopenharmony_ci */
843d0407baSopenharmony_ciunion db {
853d0407baSopenharmony_ci	struct {
863d0407baSopenharmony_ci		u32	chnl		:3;	// 0
873d0407baSopenharmony_ci		u32	reserved0	:28;	// 3:30
883d0407baSopenharmony_ci		u32	stop		:1;	// 31
893d0407baSopenharmony_ci	};
903d0407baSopenharmony_ci	u32 asdword;
913d0407baSopenharmony_ci};
923d0407baSopenharmony_ci
933d0407baSopenharmony_ci/**
943d0407baSopenharmony_ci * The Context Registers for read and write.
953d0407baSopenharmony_ci */
963d0407baSopenharmony_cistruct ctx_regs {
973d0407baSopenharmony_ci	union chan_ctrl_lo		ctrllo;
983d0407baSopenharmony_ci	union chan_ctrl_hi		ctrlhi;
993d0407baSopenharmony_ci	u32				xfersize;
1003d0407baSopenharmony_ci	u32				sarptrlo;
1013d0407baSopenharmony_ci	u32				sarptrhi;
1023d0407baSopenharmony_ci	u32				darptrlo;
1033d0407baSopenharmony_ci	u32				darptrhi;
1043d0407baSopenharmony_ci};
1053d0407baSopenharmony_ci
1063d0407baSopenharmony_ci/**
1073d0407baSopenharmony_ci * The Enable Register for read and write.
1083d0407baSopenharmony_ci */
1093d0407baSopenharmony_ciunion enb {
1103d0407baSopenharmony_ci	struct {
1113d0407baSopenharmony_ci		u32	enb		:1;	// 0
1123d0407baSopenharmony_ci		u32	reserved0	:31;	// 1:31
1133d0407baSopenharmony_ci	};
1143d0407baSopenharmony_ci	u32 asdword;
1153d0407baSopenharmony_ci};
1163d0407baSopenharmony_ci
1173d0407baSopenharmony_ci/**
1183d0407baSopenharmony_ci * The Interrupt Status Register for read and write.
1193d0407baSopenharmony_ci */
1203d0407baSopenharmony_ciunion int_status {
1213d0407baSopenharmony_ci	struct {
1223d0407baSopenharmony_ci		u32	donesta		:8;
1233d0407baSopenharmony_ci		u32	rsvd0		:8;
1243d0407baSopenharmony_ci		u32	abortsta	:8;
1253d0407baSopenharmony_ci		u32	rsvd1		:8;
1263d0407baSopenharmony_ci	};
1273d0407baSopenharmony_ci	u32 asdword;
1283d0407baSopenharmony_ci};
1293d0407baSopenharmony_ci
1303d0407baSopenharmony_ci/**
1313d0407baSopenharmony_ci * The Interrupt Clear Register for read and write.
1323d0407baSopenharmony_ci */
1333d0407baSopenharmony_ciunion int_clear {
1343d0407baSopenharmony_ci	struct {
1353d0407baSopenharmony_ci		u32	doneclr		:8;
1363d0407baSopenharmony_ci		u32	rsvd0		:8;
1373d0407baSopenharmony_ci		u32	abortclr	:8;
1383d0407baSopenharmony_ci		u32	rsvd1		:8;
1393d0407baSopenharmony_ci	};
1403d0407baSopenharmony_ci	u32 asdword;
1413d0407baSopenharmony_ci};
1423d0407baSopenharmony_ci
1433d0407baSopenharmony_cistruct dma_table {
1443d0407baSopenharmony_ci	u32				*descs;
1453d0407baSopenharmony_ci	int				chn;
1463d0407baSopenharmony_ci	phys_addr_t			phys_descs;
1473d0407baSopenharmony_ci	u32				dir;
1483d0407baSopenharmony_ci	u32				type;
1493d0407baSopenharmony_ci	struct list_head		tbl_node;
1503d0407baSopenharmony_ci	union enb			enb;
1513d0407baSopenharmony_ci	struct ctx_regs			ctx_reg;
1523d0407baSopenharmony_ci	union weight			weilo;
1533d0407baSopenharmony_ci	union weight			weihi;
1543d0407baSopenharmony_ci	union db			start;
1553d0407baSopenharmony_ci	phys_addr_t			local;
1563d0407baSopenharmony_ci	phys_addr_t			bus;
1573d0407baSopenharmony_ci	size_t				buf_size;
1583d0407baSopenharmony_ci};
1593d0407baSopenharmony_ci
1603d0407baSopenharmony_cistruct dma_trx_obj {
1613d0407baSopenharmony_ci	struct device			*dev;
1623d0407baSopenharmony_ci	int				loop_count;
1633d0407baSopenharmony_ci	int				loop_count_threshold;
1643d0407baSopenharmony_ci	void				*local_mem_base;
1653d0407baSopenharmony_ci	phys_addr_t			local_mem_start;
1663d0407baSopenharmony_ci	size_t				local_mem_size;
1673d0407baSopenharmony_ci	phys_addr_t			remote_mem_start;
1683d0407baSopenharmony_ci	void				*region_base;
1693d0407baSopenharmony_ci	phys_addr_t			region_start;
1703d0407baSopenharmony_ci	size_t				region_size;
1713d0407baSopenharmony_ci	int				dma_free;
1723d0407baSopenharmony_ci	unsigned long			local_write_available;
1733d0407baSopenharmony_ci	unsigned long			local_read_available;
1743d0407baSopenharmony_ci	unsigned long			remote_write_available;
1753d0407baSopenharmony_ci	spinlock_t			tbl_list_lock; /* lock dma table */
1763d0407baSopenharmony_ci	struct list_head		tbl_list;
1773d0407baSopenharmony_ci	struct work_struct		dma_trx_work;
1783d0407baSopenharmony_ci	wait_queue_head_t		event_queue;
1793d0407baSopenharmony_ci	struct workqueue_struct		*dma_trx_wq;
1803d0407baSopenharmony_ci	struct dma_table		*table[PCIE_DMA_TABLE_NUM];
1813d0407baSopenharmony_ci	struct dma_table		*cur;
1823d0407baSopenharmony_ci	struct hrtimer			scan_timer;
1833d0407baSopenharmony_ci	int				busno;
1843d0407baSopenharmony_ci	void				*priv;
1853d0407baSopenharmony_ci	struct completion		done;
1863d0407baSopenharmony_ci	int				ref_count;
1873d0407baSopenharmony_ci	struct mutex			count_mutex;
1883d0407baSopenharmony_ci	unsigned long			irq_num;
1893d0407baSopenharmony_ci	struct dentry			*pcie_root;
1903d0407baSopenharmony_ci	struct pcie_misc_dev		*pcie_dev;
1913d0407baSopenharmony_ci	void 				(*start_dma_func)(struct dma_trx_obj *obj);
1923d0407baSopenharmony_ci	void				(*config_dma_func)(struct dma_table *table);
1933d0407baSopenharmony_ci	ktime_t				begin;
1943d0407baSopenharmony_ci	ktime_t				end;
1953d0407baSopenharmony_ci	u64				cache_time_total;
1963d0407baSopenharmony_ci	u64				cache_time_avarage;
1973d0407baSopenharmony_ci	u32				buffer_size;
1983d0407baSopenharmony_ci	u32				rd_buf_size;
1993d0407baSopenharmony_ci	u32				wr_buf_size;
2003d0407baSopenharmony_ci	u32				ack_base;
2013d0407baSopenharmony_ci	u32				set_data_check_pos;
2023d0407baSopenharmony_ci	u32				set_local_idx_pos;
2033d0407baSopenharmony_ci	u32				set_buf_size_pos;
2043d0407baSopenharmony_ci	u32				set_chk_sum_pos;
2053d0407baSopenharmony_ci	u32				version;
2063d0407baSopenharmony_ci	int				addr_reverse;
2073d0407baSopenharmony_ci};
2083d0407baSopenharmony_ci
2093d0407baSopenharmony_ci#if IS_ENABLED(CONFIG_ROCKCHIP_PCIE_DMA_OBJ)
2103d0407baSopenharmony_cistruct dma_trx_obj *rk_pcie_dma_obj_probe(struct device *dev);
2113d0407baSopenharmony_civoid rk_pcie_dma_obj_remove(struct dma_trx_obj *obj);
2123d0407baSopenharmony_ci#else
2133d0407baSopenharmony_cistatic inline struct dma_trx_obj *rk_pcie_dma_obj_probe(struct device *dev)
2143d0407baSopenharmony_ci{
2153d0407baSopenharmony_ci	return NULL;
2163d0407baSopenharmony_ci}
2173d0407baSopenharmony_ci
2183d0407baSopenharmony_cistatic inline void rk_pcie_dma_obj_remove(struct dma_trx_obj *obj)
2193d0407baSopenharmony_ci{
2203d0407baSopenharmony_ci}
2213d0407baSopenharmony_ci#endif
2223d0407baSopenharmony_ci
2233d0407baSopenharmony_ci#endif
224