18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * linux/drivers/misc/xillybus.h
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright 2011 Xillybus Ltd, http://xillybus.com
68c2ecf20Sopenharmony_ci *
78c2ecf20Sopenharmony_ci * Header file for the Xillybus FPGA/host framework.
88c2ecf20Sopenharmony_ci */
98c2ecf20Sopenharmony_ci
108c2ecf20Sopenharmony_ci#ifndef __XILLYBUS_H
118c2ecf20Sopenharmony_ci#define __XILLYBUS_H
128c2ecf20Sopenharmony_ci
138c2ecf20Sopenharmony_ci#include <linux/list.h>
148c2ecf20Sopenharmony_ci#include <linux/device.h>
158c2ecf20Sopenharmony_ci#include <linux/dma-mapping.h>
168c2ecf20Sopenharmony_ci#include <linux/interrupt.h>
178c2ecf20Sopenharmony_ci#include <linux/sched.h>
188c2ecf20Sopenharmony_ci#include <linux/cdev.h>
198c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
208c2ecf20Sopenharmony_ci#include <linux/mutex.h>
218c2ecf20Sopenharmony_ci#include <linux/workqueue.h>
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_cistruct xilly_endpoint_hardware;
248c2ecf20Sopenharmony_ci
258c2ecf20Sopenharmony_cistruct xilly_buffer {
268c2ecf20Sopenharmony_ci	void *addr;
278c2ecf20Sopenharmony_ci	dma_addr_t dma_addr;
288c2ecf20Sopenharmony_ci	int end_offset; /* Counting elements, not bytes */
298c2ecf20Sopenharmony_ci};
308c2ecf20Sopenharmony_ci
318c2ecf20Sopenharmony_cistruct xilly_idt_handle {
328c2ecf20Sopenharmony_ci	unsigned char *chandesc;
338c2ecf20Sopenharmony_ci	unsigned char *idt;
348c2ecf20Sopenharmony_ci	int entries;
358c2ecf20Sopenharmony_ci};
368c2ecf20Sopenharmony_ci
378c2ecf20Sopenharmony_ci/*
388c2ecf20Sopenharmony_ci * Read-write confusion: wr_* and rd_* notation sticks to FPGA view, so
398c2ecf20Sopenharmony_ci * wr_* buffers are those consumed by read(), since the FPGA writes to them
408c2ecf20Sopenharmony_ci * and vice versa.
418c2ecf20Sopenharmony_ci */
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_cistruct xilly_channel {
448c2ecf20Sopenharmony_ci	struct xilly_endpoint *endpoint;
458c2ecf20Sopenharmony_ci	int chan_num;
468c2ecf20Sopenharmony_ci	int log2_element_size;
478c2ecf20Sopenharmony_ci	int seekable;
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci	struct xilly_buffer **wr_buffers; /* FPGA writes, driver reads! */
508c2ecf20Sopenharmony_ci	int num_wr_buffers;
518c2ecf20Sopenharmony_ci	unsigned int wr_buf_size; /* In bytes */
528c2ecf20Sopenharmony_ci	int wr_fpga_buf_idx;
538c2ecf20Sopenharmony_ci	int wr_host_buf_idx;
548c2ecf20Sopenharmony_ci	int wr_host_buf_pos;
558c2ecf20Sopenharmony_ci	int wr_empty;
568c2ecf20Sopenharmony_ci	int wr_ready; /* Significant only when wr_empty == 1 */
578c2ecf20Sopenharmony_ci	int wr_sleepy;
588c2ecf20Sopenharmony_ci	int wr_eof;
598c2ecf20Sopenharmony_ci	int wr_hangup;
608c2ecf20Sopenharmony_ci	spinlock_t wr_spinlock;
618c2ecf20Sopenharmony_ci	struct mutex wr_mutex;
628c2ecf20Sopenharmony_ci	wait_queue_head_t wr_wait;
638c2ecf20Sopenharmony_ci	wait_queue_head_t wr_ready_wait;
648c2ecf20Sopenharmony_ci	int wr_ref_count;
658c2ecf20Sopenharmony_ci	int wr_synchronous;
668c2ecf20Sopenharmony_ci	int wr_allow_partial;
678c2ecf20Sopenharmony_ci	int wr_exclusive_open;
688c2ecf20Sopenharmony_ci	int wr_supports_nonempty;
698c2ecf20Sopenharmony_ci
708c2ecf20Sopenharmony_ci	struct xilly_buffer **rd_buffers; /* FPGA reads, driver writes! */
718c2ecf20Sopenharmony_ci	int num_rd_buffers;
728c2ecf20Sopenharmony_ci	unsigned int rd_buf_size; /* In bytes */
738c2ecf20Sopenharmony_ci	int rd_fpga_buf_idx;
748c2ecf20Sopenharmony_ci	int rd_host_buf_pos;
758c2ecf20Sopenharmony_ci	int rd_host_buf_idx;
768c2ecf20Sopenharmony_ci	int rd_full;
778c2ecf20Sopenharmony_ci	spinlock_t rd_spinlock;
788c2ecf20Sopenharmony_ci	struct mutex rd_mutex;
798c2ecf20Sopenharmony_ci	wait_queue_head_t rd_wait;
808c2ecf20Sopenharmony_ci	int rd_ref_count;
818c2ecf20Sopenharmony_ci	int rd_allow_partial;
828c2ecf20Sopenharmony_ci	int rd_synchronous;
838c2ecf20Sopenharmony_ci	int rd_exclusive_open;
848c2ecf20Sopenharmony_ci	struct delayed_work rd_workitem;
858c2ecf20Sopenharmony_ci	unsigned char rd_leftovers[4];
868c2ecf20Sopenharmony_ci};
878c2ecf20Sopenharmony_ci
888c2ecf20Sopenharmony_cistruct xilly_endpoint {
898c2ecf20Sopenharmony_ci	/*
908c2ecf20Sopenharmony_ci	 * One of pdev and dev is always NULL, and the other is a valid
918c2ecf20Sopenharmony_ci	 * pointer, depending on the type of device
928c2ecf20Sopenharmony_ci	 */
938c2ecf20Sopenharmony_ci	struct pci_dev *pdev;
948c2ecf20Sopenharmony_ci	struct device *dev;
958c2ecf20Sopenharmony_ci	struct xilly_endpoint_hardware *ephw;
968c2ecf20Sopenharmony_ci
978c2ecf20Sopenharmony_ci	struct list_head ep_list;
988c2ecf20Sopenharmony_ci	int dma_using_dac; /* =1 if 64-bit DMA is used, =0 otherwise. */
998c2ecf20Sopenharmony_ci	__iomem void *registers;
1008c2ecf20Sopenharmony_ci	int fatal_error;
1018c2ecf20Sopenharmony_ci
1028c2ecf20Sopenharmony_ci	struct mutex register_mutex;
1038c2ecf20Sopenharmony_ci	wait_queue_head_t ep_wait;
1048c2ecf20Sopenharmony_ci
1058c2ecf20Sopenharmony_ci	/* Channels and message handling */
1068c2ecf20Sopenharmony_ci	struct cdev cdev;
1078c2ecf20Sopenharmony_ci
1088c2ecf20Sopenharmony_ci	int major;
1098c2ecf20Sopenharmony_ci	int lowest_minor; /* Highest minor = lowest_minor + num_channels - 1 */
1108c2ecf20Sopenharmony_ci
1118c2ecf20Sopenharmony_ci	int num_channels; /* EXCLUDING message buffer */
1128c2ecf20Sopenharmony_ci	struct xilly_channel **channels;
1138c2ecf20Sopenharmony_ci	int msg_counter;
1148c2ecf20Sopenharmony_ci	int failed_messages;
1158c2ecf20Sopenharmony_ci	int idtlen;
1168c2ecf20Sopenharmony_ci
1178c2ecf20Sopenharmony_ci	u32 *msgbuf_addr;
1188c2ecf20Sopenharmony_ci	dma_addr_t msgbuf_dma_addr;
1198c2ecf20Sopenharmony_ci	unsigned int msg_buf_size;
1208c2ecf20Sopenharmony_ci};
1218c2ecf20Sopenharmony_ci
1228c2ecf20Sopenharmony_cistruct xilly_endpoint_hardware {
1238c2ecf20Sopenharmony_ci	struct module *owner;
1248c2ecf20Sopenharmony_ci	void (*hw_sync_sgl_for_cpu)(struct xilly_endpoint *,
1258c2ecf20Sopenharmony_ci				    dma_addr_t,
1268c2ecf20Sopenharmony_ci				    size_t,
1278c2ecf20Sopenharmony_ci				    int);
1288c2ecf20Sopenharmony_ci	void (*hw_sync_sgl_for_device)(struct xilly_endpoint *,
1298c2ecf20Sopenharmony_ci				       dma_addr_t,
1308c2ecf20Sopenharmony_ci				       size_t,
1318c2ecf20Sopenharmony_ci				       int);
1328c2ecf20Sopenharmony_ci	int (*map_single)(struct xilly_endpoint *,
1338c2ecf20Sopenharmony_ci			  void *,
1348c2ecf20Sopenharmony_ci			  size_t,
1358c2ecf20Sopenharmony_ci			  int,
1368c2ecf20Sopenharmony_ci			  dma_addr_t *);
1378c2ecf20Sopenharmony_ci};
1388c2ecf20Sopenharmony_ci
1398c2ecf20Sopenharmony_cistruct xilly_mapping {
1408c2ecf20Sopenharmony_ci	void *device;
1418c2ecf20Sopenharmony_ci	dma_addr_t dma_addr;
1428c2ecf20Sopenharmony_ci	size_t size;
1438c2ecf20Sopenharmony_ci	int direction;
1448c2ecf20Sopenharmony_ci};
1458c2ecf20Sopenharmony_ci
1468c2ecf20Sopenharmony_ciirqreturn_t xillybus_isr(int irq, void *data);
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_cistruct xilly_endpoint *xillybus_init_endpoint(struct pci_dev *pdev,
1498c2ecf20Sopenharmony_ci					      struct device *dev,
1508c2ecf20Sopenharmony_ci					      struct xilly_endpoint_hardware
1518c2ecf20Sopenharmony_ci					      *ephw);
1528c2ecf20Sopenharmony_ci
1538c2ecf20Sopenharmony_ciint xillybus_endpoint_discovery(struct xilly_endpoint *endpoint);
1548c2ecf20Sopenharmony_ci
1558c2ecf20Sopenharmony_civoid xillybus_endpoint_remove(struct xilly_endpoint *endpoint);
1568c2ecf20Sopenharmony_ci
1578c2ecf20Sopenharmony_ci#endif /* __XILLYBUS_H */
158