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