/* SPDX-License-Identifier: GPL-2.0-only1*2* Copyright (c) 2019-2021, The Linux Foundation. All rights reserved.3* Copyright (c) 2021-2023 Qualcomm Innovation Center, Inc. All rights reserved.4*/56#ifndef _QAIC_H_7#define _QAIC_H_89#include <linux/interrupt.h>10#include <linux/kref.h>11#include <linux/mhi.h>12#include <linux/mutex.h>13#include <linux/pci.h>14#include <linux/spinlock.h>15#include <linux/srcu.h>16#include <linux/wait.h>17#include <linux/workqueue.h>18#include <drm/drm_device.h>19#include <drm/drm_gem.h>2021#define QAIC_DBC_BASE SZ_128K22#define QAIC_DBC_SIZE SZ_4K2324#define QAIC_NO_PARTITION -12526#define QAIC_DBC_OFF(i) ((i) * QAIC_DBC_SIZE + QAIC_DBC_BASE)2728#define to_qaic_bo(obj) container_of(obj, struct qaic_bo, base)29#define to_qaic_drm_device(dev) container_of(dev, struct qaic_drm_device, drm)30#define to_drm(qddev) (&(qddev)->drm)31#define to_accel_kdev(qddev) (to_drm(qddev)->accel->kdev) /* Return Linux device of accel node */32#define to_qaic_device(dev) (to_qaic_drm_device((dev))->qdev)3334enum aic_families {35FAMILY_AIC100,36FAMILY_AIC200,37FAMILY_MAX,38};3940enum __packed dev_states {41/* Device is offline or will be very soon */42QAIC_OFFLINE,43/* Device is booting, not clear if it's in a usable state */44QAIC_BOOT,45/* Device is fully operational */46QAIC_ONLINE,47};4849extern bool datapath_polling;5051struct qaic_user {52/* Uniquely identifies this user for the device */53int handle;54struct kref ref_count;55/* Char device opened by this user */56struct qaic_drm_device *qddev;57/* Node in list of users that opened this drm device */58struct list_head node;59/* SRCU used to synchronize this user during cleanup */60struct srcu_struct qddev_lock;61atomic_t chunk_id;62};6364struct dma_bridge_chan {65/* Pointer to device strcut maintained by driver */66struct qaic_device *qdev;67/* ID of this DMA bridge channel(DBC) */68unsigned int id;69/* Synchronizes access to xfer_list */70spinlock_t xfer_lock;71/* Base address of request queue */72void *req_q_base;73/* Base address of response queue */74void *rsp_q_base;75/*76* Base bus address of request queue. Response queue bus address can be77* calculated by adding request queue size to this variable78*/79dma_addr_t dma_addr;80/* Total size of request and response queue in byte */81u32 total_size;82/* Capacity of request/response queue */83u32 nelem;84/* The user that opened this DBC */85struct qaic_user *usr;86/*87* Request ID of next memory handle that goes in request queue. One88* memory handle can enqueue more than one request elements, all89* this requests that belong to same memory handle have same request ID90*/91u16 next_req_id;92/* true: DBC is in use; false: DBC not in use */93bool in_use;94/*95* Base address of device registers. Used to read/write request and96* response queue's head and tail pointer of this DBC.97*/98void __iomem *dbc_base;99/* Head of list where each node is a memory handle queued in request queue */100struct list_head xfer_list;101/* Synchronizes DBC readers during cleanup */102struct srcu_struct ch_lock;103/*104* When this DBC is released, any thread waiting on this wait queue is105* woken up106*/107wait_queue_head_t dbc_release;108/* Head of list where each node is a bo associated with this DBC */109struct list_head bo_lists;110/* The irq line for this DBC. Used for polling */111unsigned int irq;112/* Polling work item to simulate interrupts */113struct work_struct poll_work;114};115116struct qaic_device {117/* Pointer to base PCI device struct of our physical device */118struct pci_dev *pdev;119/* Req. ID of request that will be queued next in MHI control device */120u32 next_seq_num;121/* Base address of the MHI bar */122void __iomem *bar_mhi;123/* Base address of the DBCs bar */124void __iomem *bar_dbc;125/* Controller structure for MHI devices */126struct mhi_controller *mhi_cntrl;127/* MHI control channel device */128struct mhi_device *cntl_ch;129/* List of requests queued in MHI control device */130struct list_head cntl_xfer_list;131/* Synchronizes MHI control device transactions and its xfer list */132struct mutex cntl_mutex;133/* Array of DBC struct of this device */134struct dma_bridge_chan *dbc;135/* Work queue for tasks related to MHI control device */136struct workqueue_struct *cntl_wq;137/* Synchronizes all the users of device during cleanup */138struct srcu_struct dev_lock;139/* Track the state of the device during resets */140enum dev_states dev_state;141/* true: single MSI is used to operate device */142bool single_msi;143/*144* true: A tx MHI transaction has failed and a rx buffer is still queued145* in control device. Such a buffer is considered lost rx buffer146* false: No rx buffer is lost in control device147*/148bool cntl_lost_buf;149/* Maximum number of DBC supported by this device */150u32 num_dbc;151/* Reference to the drm_device for this device when it is created */152struct qaic_drm_device *qddev;153/* Generate the CRC of a control message */154u32 (*gen_crc)(void *msg);155/* Validate the CRC of a control message */156bool (*valid_crc)(void *msg);157/* MHI "QAIC_TIMESYNC" channel device */158struct mhi_device *qts_ch;159/* Work queue for tasks related to MHI "QAIC_TIMESYNC" channel */160struct workqueue_struct *qts_wq;161/* Head of list of page allocated by MHI bootlog device */162struct list_head bootlog;163/* MHI bootlog channel device */164struct mhi_device *bootlog_ch;165/* Work queue for tasks related to MHI bootlog device */166struct workqueue_struct *bootlog_wq;167/* Synchronizes access of pages in MHI bootlog device */168struct mutex bootlog_mutex;169/* MHI RAS channel device */170struct mhi_device *ras_ch;171/* Correctable error count */172unsigned int ce_count;173/* Un-correctable error count */174unsigned int ue_count;175/* Un-correctable non-fatal error count */176unsigned int ue_nf_count;177};178179struct qaic_drm_device {180/* The drm device struct of this drm device */181struct drm_device drm;182/* Pointer to the root device struct driven by this driver */183struct qaic_device *qdev;184/*185* The physical device can be partition in number of logical devices.186* And each logical device is given a partition id. This member stores187* that id. QAIC_NO_PARTITION is a sentinel used to mark that this drm188* device is the actual physical device189*/190s32 partition_id;191/* Head in list of users who have opened this drm device */192struct list_head users;193/* Synchronizes access to users list */194struct mutex users_mutex;195};196197struct qaic_bo {198struct drm_gem_object base;199/* Scatter/gather table for allocate/imported BO */200struct sg_table *sgt;201/* Head in list of slices of this BO */202struct list_head slices;203/* Total nents, for all slices of this BO */204int total_slice_nents;205/*206* Direction of transfer. It can assume only two value DMA_TO_DEVICE and207* DMA_FROM_DEVICE.208*/209int dir;210/* The pointer of the DBC which operates on this BO */211struct dma_bridge_chan *dbc;212/* Number of slice that belongs to this buffer */213u32 nr_slice;214/* Number of slice that have been transferred by DMA engine */215u32 nr_slice_xfer_done;216/*217* If true then user has attached slicing information to this BO by218* calling DRM_IOCTL_QAIC_ATTACH_SLICE_BO ioctl.219*/220bool sliced;221/* Request ID of this BO if it is queued for execution */222u16 req_id;223/* Wait on this for completion of DMA transfer of this BO */224struct completion xfer_done;225/*226* Node in linked list where head is dbc->xfer_list.227* This link list contain BO's that are queued for DMA transfer.228*/229struct list_head xfer_list;230/*231* Node in linked list where head is dbc->bo_lists.232* This link list contain BO's that are associated with the DBC it is233* linked to.234*/235struct list_head bo_list;236struct {237/*238* Latest timestamp(ns) at which kernel received a request to239* execute this BO240*/241u64 req_received_ts;242/*243* Latest timestamp(ns) at which kernel enqueued requests of244* this BO for execution in DMA queue245*/246u64 req_submit_ts;247/*248* Latest timestamp(ns) at which kernel received a completion249* interrupt for requests of this BO250*/251u64 req_processed_ts;252/*253* Number of elements already enqueued in DMA queue before254* enqueuing requests of this BO255*/256u32 queue_level_before;257} perf_stats;258/* Synchronizes BO operations */259struct mutex lock;260};261262struct bo_slice {263/* Mapped pages */264struct sg_table *sgt;265/* Number of requests required to queue in DMA queue */266int nents;267/* See enum dma_data_direction */268int dir;269/* Actual requests that will be copied in DMA queue */270struct dbc_req *reqs;271struct kref ref_count;272/* true: No DMA transfer required */273bool no_xfer;274/* Pointer to the parent BO handle */275struct qaic_bo *bo;276/* Node in list of slices maintained by parent BO */277struct list_head slice;278/* Size of this slice in bytes */279u64 size;280/* Offset of this slice in buffer */281u64 offset;282};283284int get_dbc_req_elem_size(void);285int get_dbc_rsp_elem_size(void);286int get_cntl_version(struct qaic_device *qdev, struct qaic_user *usr, u16 *major, u16 *minor);287int qaic_manage_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);288void qaic_mhi_ul_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result);289290void qaic_mhi_dl_xfer_cb(struct mhi_device *mhi_dev, struct mhi_result *mhi_result);291292int qaic_control_open(struct qaic_device *qdev);293void qaic_control_close(struct qaic_device *qdev);294void qaic_release_usr(struct qaic_device *qdev, struct qaic_user *usr);295296irqreturn_t dbc_irq_threaded_fn(int irq, void *data);297irqreturn_t dbc_irq_handler(int irq, void *data);298int disable_dbc(struct qaic_device *qdev, u32 dbc_id, struct qaic_user *usr);299void enable_dbc(struct qaic_device *qdev, u32 dbc_id, struct qaic_user *usr);300void wakeup_dbc(struct qaic_device *qdev, u32 dbc_id);301void release_dbc(struct qaic_device *qdev, u32 dbc_id);302void qaic_data_get_fifo_info(struct dma_bridge_chan *dbc, u32 *head, u32 *tail);303304void wake_all_cntl(struct qaic_device *qdev);305void qaic_dev_reset_clean_local_state(struct qaic_device *qdev);306307struct drm_gem_object *qaic_gem_prime_import(struct drm_device *dev, struct dma_buf *dma_buf);308309int qaic_create_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);310int qaic_mmap_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);311int qaic_attach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);312int qaic_execute_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);313int qaic_partial_execute_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);314int qaic_wait_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);315int qaic_perf_stats_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);316int qaic_detach_slice_bo_ioctl(struct drm_device *dev, void *data, struct drm_file *file_priv);317void irq_polling_work(struct work_struct *work);318319#endif /* _QAIC_H_ */320321322