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