• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /* SPDX-License-Identifier: GPL-2.0+ */
2 #ifndef KPC_DMA_DRIVER_H
3 #define KPC_DMA_DRIVER_H
4 #include <linux/platform_device.h>
5 #include <linux/cdev.h>
6 #include <linux/kfifo.h>
7 #include <linux/list.h>
8 #include <linux/spinlock.h>
9 #include <linux/sched.h>
10 #include <linux/miscdevice.h>
11 #include <linux/rwsem.h>
12 #include <linux/dma-mapping.h>
13 #include <linux/dmapool.h>
14 #include <linux/pci.h>
15 #include <linux/interrupt.h>
16 #include <linux/workqueue.h>
17 #include <linux/bitops.h>
18 #include "../kpc.h"
19 
20 struct kp2000_device;
21 struct kpc_dma_device {
22 	struct list_head            list;
23 	struct platform_device     *pldev;
24 	u32 __iomem                *eng_regs;
25 	struct device              *kpc_dma_dev;
26 	struct kobject              kobj;
27 	char                        name[16];
28 
29 	int                         dir; // DMA_FROM_DEVICE || DMA_TO_DEVICE
30 	struct mutex                sem;
31 	unsigned int                irq;
32 	struct work_struct          irq_work;
33 
34 	atomic_t                    open_count;
35 
36 	size_t                      accumulated_bytes;
37 	u32                         accumulated_flags;
38 
39 	// Descriptor "Pool" housekeeping
40 	u32                         desc_pool_cnt;
41 	struct dma_pool            *desc_pool;
42 	struct kpc_dma_descriptor  *desc_pool_first;
43 	struct kpc_dma_descriptor  *desc_pool_last;
44 
45 	struct kpc_dma_descriptor  *desc_next;
46 	struct kpc_dma_descriptor  *desc_completed;
47 };
48 
49 struct dev_private_data {
50 	struct kpc_dma_device      *ldev;
51 	u64                         card_addr;
52 	u64                         user_ctl;
53 	u64                         user_ctl_last;
54 	u64                         user_sts;
55 };
56 
57 struct kpc_dma_device *kpc_dma_lookup_device(int minor);
58 
59 extern const struct file_operations  kpc_dma_fops;
60 
61 #define ENG_CAP_PRESENT                 0x00000001
62 #define ENG_CAP_DIRECTION               0x00000002
63 #define ENG_CAP_TYPE_MASK               0x000000F0
64 #define ENG_CAP_NUMBER_MASK             0x0000FF00
65 #define ENG_CAP_CARD_ADDR_SIZE_MASK     0x007F0000
66 #define ENG_CAP_DESC_MAX_BYTE_CNT_MASK  0x3F000000
67 #define ENG_CAP_PERF_SCALE_MASK         0xC0000000
68 
69 #define ENG_CTL_IRQ_ENABLE              BIT(0)
70 #define ENG_CTL_IRQ_ACTIVE              BIT(1)
71 #define ENG_CTL_DESC_COMPLETE           BIT(2)
72 #define ENG_CTL_DESC_ALIGN_ERR          BIT(3)
73 #define ENG_CTL_DESC_FETCH_ERR          BIT(4)
74 #define ENG_CTL_SW_ABORT_ERR            BIT(5)
75 #define ENG_CTL_DESC_CHAIN_END          BIT(7)
76 #define ENG_CTL_DMA_ENABLE              BIT(8)
77 #define ENG_CTL_DMA_RUNNING             BIT(10)
78 #define ENG_CTL_DMA_WAITING             BIT(11)
79 #define ENG_CTL_DMA_WAITING_PERSIST     BIT(12)
80 #define ENG_CTL_DMA_RESET_REQUEST       BIT(14)
81 #define ENG_CTL_DMA_RESET               BIT(15)
82 #define ENG_CTL_DESC_FETCH_ERR_CLASS_MASK   0x700000
83 
84 struct aio_cb_data {
85 	struct dev_private_data    *priv;
86 	struct kpc_dma_device      *ldev;
87 	struct completion  *cpl;
88 	unsigned char       flags;
89 	size_t              len;
90 
91 	unsigned int        page_count;
92 	struct page       **user_pages;
93 	struct sg_table     sgt;
94 	int                 mapped_entry_count;
95 };
96 
97 #define ACD_FLAG_DONE               0
98 #define ACD_FLAG_ABORT              1
99 #define ACD_FLAG_ENG_ACCUM_ERROR    4
100 #define ACD_FLAG_ENG_ACCUM_SHORT    5
101 
102 struct kpc_dma_descriptor {
103 	struct {
104 		volatile u32  DescByteCount              :20;
105 		volatile u32  DescStatusErrorFlags       :4;
106 		volatile u32  DescStatusFlags            :8;
107 	};
108 		volatile u32  DescUserControlLS;
109 		volatile u32  DescUserControlMS;
110 		volatile u32  DescCardAddrLS;
111 	struct {
112 		volatile u32  DescBufferByteCount        :20;
113 		volatile u32  DescCardAddrMS             :4;
114 		volatile u32  DescControlFlags           :8;
115 	};
116 		volatile u32  DescSystemAddrLS;
117 		volatile u32  DescSystemAddrMS;
118 		volatile u32  DescNextDescPtr;
119 
120 		dma_addr_t    MyDMAAddr;
121 		struct kpc_dma_descriptor   *Next;
122 
123 		struct aio_cb_data  *acd;
124 } __attribute__((packed));
125 // DescControlFlags:
126 #define DMA_DESC_CTL_SOP            BIT(7)
127 #define DMA_DESC_CTL_EOP            BIT(6)
128 #define DMA_DESC_CTL_AFIFO          BIT(2)
129 #define DMA_DESC_CTL_IRQONERR       BIT(1)
130 #define DMA_DESC_CTL_IRQONDONE      BIT(0)
131 // DescStatusFlags:
132 #define DMA_DESC_STS_SOP            BIT(7)
133 #define DMA_DESC_STS_EOP            BIT(6)
134 #define DMA_DESC_STS_ERROR          BIT(4)
135 #define DMA_DESC_STS_USMSZ          BIT(3)
136 #define DMA_DESC_STS_USLSZ          BIT(2)
137 #define DMA_DESC_STS_SHORT          BIT(1)
138 #define DMA_DESC_STS_COMPLETE       BIT(0)
139 // DescStatusErrorFlags:
140 #define DMA_DESC_ESTS_ECRC          BIT(2)
141 #define DMA_DESC_ESTS_POISON        BIT(1)
142 #define DMA_DESC_ESTS_UNSUCCESSFUL  BIT(0)
143 
144 #define DMA_DESC_ALIGNMENT          0x20
145 
146 static inline
GetEngineCapabilities(struct kpc_dma_device * eng)147 u32  GetEngineCapabilities(struct kpc_dma_device *eng)
148 {
149 	return readl(eng->eng_regs + 0);
150 }
151 
152 static inline
WriteEngineControl(struct kpc_dma_device * eng,u32 value)153 void  WriteEngineControl(struct kpc_dma_device *eng, u32 value)
154 {
155 	writel(value, eng->eng_regs + 1);
156 }
157 
158 static inline
GetEngineControl(struct kpc_dma_device * eng)159 u32  GetEngineControl(struct kpc_dma_device *eng)
160 {
161 	return readl(eng->eng_regs + 1);
162 }
163 
164 static inline
SetClearEngineControl(struct kpc_dma_device * eng,u32 set_bits,u32 clear_bits)165 void  SetClearEngineControl(struct kpc_dma_device *eng, u32 set_bits, u32 clear_bits)
166 {
167 	u32 val = GetEngineControl(eng);
168 
169 	val |= set_bits;
170 	val &= ~clear_bits;
171 	WriteEngineControl(eng, val);
172 }
173 
174 static inline
SetEngineNextPtr(struct kpc_dma_device * eng,struct kpc_dma_descriptor * desc)175 void  SetEngineNextPtr(struct kpc_dma_device *eng, struct kpc_dma_descriptor *desc)
176 {
177 	writel(desc->MyDMAAddr, eng->eng_regs + 2);
178 }
179 
180 static inline
SetEngineSWPtr(struct kpc_dma_device * eng,struct kpc_dma_descriptor * desc)181 void  SetEngineSWPtr(struct kpc_dma_device *eng, struct kpc_dma_descriptor *desc)
182 {
183 	writel(desc->MyDMAAddr, eng->eng_regs + 3);
184 }
185 
186 static inline
ClearEngineCompletePtr(struct kpc_dma_device * eng)187 void  ClearEngineCompletePtr(struct kpc_dma_device *eng)
188 {
189 	writel(0, eng->eng_regs + 4);
190 }
191 
192 static inline
GetEngineCompletePtr(struct kpc_dma_device * eng)193 u32  GetEngineCompletePtr(struct kpc_dma_device *eng)
194 {
195 	return readl(eng->eng_regs + 4);
196 }
197 
198 static inline
lock_engine(struct kpc_dma_device * eng)199 void  lock_engine(struct kpc_dma_device *eng)
200 {
201 	BUG_ON(!eng);
202 	mutex_lock(&eng->sem);
203 }
204 
205 static inline
unlock_engine(struct kpc_dma_device * eng)206 void  unlock_engine(struct kpc_dma_device *eng)
207 {
208 	BUG_ON(!eng);
209 	mutex_unlock(&eng->sem);
210 }
211 
212 /// Shared Functions
213 void  start_dma_engine(struct kpc_dma_device *eng);
214 int   setup_dma_engine(struct kpc_dma_device *eng, u32 desc_cnt);
215 void  stop_dma_engine(struct kpc_dma_device *eng);
216 void  destroy_dma_engine(struct kpc_dma_device *eng);
217 void  clear_desc(struct kpc_dma_descriptor *desc);
218 int   count_descriptors_available(struct kpc_dma_device *eng);
219 void  transfer_complete_cb(struct aio_cb_data *acd, size_t xfr_count, u32 flags);
220 
221 #endif /* KPC_DMA_DRIVER_H */
222 
223