18c2ecf20Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */
28c2ecf20Sopenharmony_ci/*
38c2ecf20Sopenharmony_ci * Most ISHTP provider device and ISHTP logic declarations
48c2ecf20Sopenharmony_ci *
58c2ecf20Sopenharmony_ci * Copyright (c) 2003-2016, Intel Corporation.
68c2ecf20Sopenharmony_ci */
78c2ecf20Sopenharmony_ci
88c2ecf20Sopenharmony_ci#ifndef _ISHTP_DEV_H_
98c2ecf20Sopenharmony_ci#define _ISHTP_DEV_H_
108c2ecf20Sopenharmony_ci
118c2ecf20Sopenharmony_ci#include <linux/types.h>
128c2ecf20Sopenharmony_ci#include <linux/spinlock.h>
138c2ecf20Sopenharmony_ci#include "bus.h"
148c2ecf20Sopenharmony_ci#include "hbm.h"
158c2ecf20Sopenharmony_ci
168c2ecf20Sopenharmony_ci#define	IPC_PAYLOAD_SIZE	128
178c2ecf20Sopenharmony_ci#define ISHTP_RD_MSG_BUF_SIZE	IPC_PAYLOAD_SIZE
188c2ecf20Sopenharmony_ci#define	IPC_FULL_MSG_SIZE	132
198c2ecf20Sopenharmony_ci
208c2ecf20Sopenharmony_ci/* Number of messages to be held in ISR->BH FIFO */
218c2ecf20Sopenharmony_ci#define	RD_INT_FIFO_SIZE	64
228c2ecf20Sopenharmony_ci
238c2ecf20Sopenharmony_ci/*
248c2ecf20Sopenharmony_ci * Number of IPC messages to be held in Tx FIFO, to be sent by ISR -
258c2ecf20Sopenharmony_ci * Tx complete interrupt or RX_COMPLETE handler
268c2ecf20Sopenharmony_ci */
278c2ecf20Sopenharmony_ci#define	IPC_TX_FIFO_SIZE	512
288c2ecf20Sopenharmony_ci
298c2ecf20Sopenharmony_ci/*
308c2ecf20Sopenharmony_ci * Number of Maximum ISHTP Clients
318c2ecf20Sopenharmony_ci */
328c2ecf20Sopenharmony_ci#define ISHTP_CLIENTS_MAX 256
338c2ecf20Sopenharmony_ci
348c2ecf20Sopenharmony_ci/*
358c2ecf20Sopenharmony_ci * Number of File descriptors/handles
368c2ecf20Sopenharmony_ci * that can be opened to the driver.
378c2ecf20Sopenharmony_ci *
388c2ecf20Sopenharmony_ci * Limit to 255: 256 Total Clients
398c2ecf20Sopenharmony_ci * minus internal client for ISHTP Bus Messages
408c2ecf20Sopenharmony_ci */
418c2ecf20Sopenharmony_ci#define ISHTP_MAX_OPEN_HANDLE_COUNT (ISHTP_CLIENTS_MAX - 1)
428c2ecf20Sopenharmony_ci
438c2ecf20Sopenharmony_ci/* Internal Clients Number */
448c2ecf20Sopenharmony_ci#define ISHTP_HOST_CLIENT_ID_ANY		(-1)
458c2ecf20Sopenharmony_ci#define ISHTP_HBM_HOST_CLIENT_ID		0
468c2ecf20Sopenharmony_ci
478c2ecf20Sopenharmony_ci#define	MAX_DMA_DELAY	20
488c2ecf20Sopenharmony_ci
498c2ecf20Sopenharmony_ci/* ISHTP device states */
508c2ecf20Sopenharmony_cienum ishtp_dev_state {
518c2ecf20Sopenharmony_ci	ISHTP_DEV_INITIALIZING = 0,
528c2ecf20Sopenharmony_ci	ISHTP_DEV_INIT_CLIENTS,
538c2ecf20Sopenharmony_ci	ISHTP_DEV_ENABLED,
548c2ecf20Sopenharmony_ci	ISHTP_DEV_RESETTING,
558c2ecf20Sopenharmony_ci	ISHTP_DEV_DISABLED,
568c2ecf20Sopenharmony_ci	ISHTP_DEV_POWER_DOWN,
578c2ecf20Sopenharmony_ci	ISHTP_DEV_POWER_UP
588c2ecf20Sopenharmony_ci};
598c2ecf20Sopenharmony_ciconst char *ishtp_dev_state_str(int state);
608c2ecf20Sopenharmony_ci
618c2ecf20Sopenharmony_cistruct ishtp_cl;
628c2ecf20Sopenharmony_ci
638c2ecf20Sopenharmony_ci/**
648c2ecf20Sopenharmony_ci * struct ishtp_fw_client - representation of fw client
658c2ecf20Sopenharmony_ci *
668c2ecf20Sopenharmony_ci * @props - client properties
678c2ecf20Sopenharmony_ci * @client_id - fw client id
688c2ecf20Sopenharmony_ci */
698c2ecf20Sopenharmony_cistruct ishtp_fw_client {
708c2ecf20Sopenharmony_ci	struct ishtp_client_properties props;
718c2ecf20Sopenharmony_ci	uint8_t client_id;
728c2ecf20Sopenharmony_ci};
738c2ecf20Sopenharmony_ci
748c2ecf20Sopenharmony_ci/*
758c2ecf20Sopenharmony_ci * Control info for IPC messages ISHTP/IPC sending FIFO -
768c2ecf20Sopenharmony_ci * list with inline data buffer
778c2ecf20Sopenharmony_ci * This structure will be filled with parameters submitted
788c2ecf20Sopenharmony_ci * by the caller glue layer
798c2ecf20Sopenharmony_ci * 'buf' may be pointing to the external buffer or to 'inline_data'
808c2ecf20Sopenharmony_ci * 'offset' will be initialized to 0 by submitting
818c2ecf20Sopenharmony_ci *
828c2ecf20Sopenharmony_ci * 'ipc_send_compl' is intended for use by clients that send fragmented
838c2ecf20Sopenharmony_ci * messages. When a fragment is sent down to IPC msg regs,
848c2ecf20Sopenharmony_ci * it will be called.
858c2ecf20Sopenharmony_ci * If it has more fragments to send, it will do it. With last fragment
868c2ecf20Sopenharmony_ci * it will send appropriate ISHTP "message-complete" flag.
878c2ecf20Sopenharmony_ci * It will remove the outstanding message
888c2ecf20Sopenharmony_ci * (mark outstanding buffer as available).
898c2ecf20Sopenharmony_ci * If counting flow control is in work and there are more flow control
908c2ecf20Sopenharmony_ci * credits, it can put the next client message queued in cl.
918c2ecf20Sopenharmony_ci * structure for IPC processing.
928c2ecf20Sopenharmony_ci *
938c2ecf20Sopenharmony_ci */
948c2ecf20Sopenharmony_cistruct wr_msg_ctl_info {
958c2ecf20Sopenharmony_ci	/* Will be called with 'ipc_send_compl_prm' as parameter */
968c2ecf20Sopenharmony_ci	void (*ipc_send_compl)(void *);
978c2ecf20Sopenharmony_ci
988c2ecf20Sopenharmony_ci	void *ipc_send_compl_prm;
998c2ecf20Sopenharmony_ci	size_t length;
1008c2ecf20Sopenharmony_ci	struct list_head	link;
1018c2ecf20Sopenharmony_ci	unsigned char	inline_data[IPC_FULL_MSG_SIZE];
1028c2ecf20Sopenharmony_ci};
1038c2ecf20Sopenharmony_ci
1048c2ecf20Sopenharmony_ci/*
1058c2ecf20Sopenharmony_ci * The ISHTP layer talks to hardware IPC message using the following
1068c2ecf20Sopenharmony_ci * callbacks
1078c2ecf20Sopenharmony_ci */
1088c2ecf20Sopenharmony_cistruct ishtp_hw_ops {
1098c2ecf20Sopenharmony_ci	int	(*hw_reset)(struct ishtp_device *dev);
1108c2ecf20Sopenharmony_ci	int	(*ipc_reset)(struct ishtp_device *dev);
1118c2ecf20Sopenharmony_ci	uint32_t (*ipc_get_header)(struct ishtp_device *dev, int length,
1128c2ecf20Sopenharmony_ci				   int busy);
1138c2ecf20Sopenharmony_ci	int	(*write)(struct ishtp_device *dev,
1148c2ecf20Sopenharmony_ci		void (*ipc_send_compl)(void *), void *ipc_send_compl_prm,
1158c2ecf20Sopenharmony_ci		unsigned char *msg, int length);
1168c2ecf20Sopenharmony_ci	uint32_t	(*ishtp_read_hdr)(const struct ishtp_device *dev);
1178c2ecf20Sopenharmony_ci	int	(*ishtp_read)(struct ishtp_device *dev, unsigned char *buffer,
1188c2ecf20Sopenharmony_ci			unsigned long buffer_length);
1198c2ecf20Sopenharmony_ci	uint32_t	(*get_fw_status)(struct ishtp_device *dev);
1208c2ecf20Sopenharmony_ci	void	(*sync_fw_clock)(struct ishtp_device *dev);
1218c2ecf20Sopenharmony_ci};
1228c2ecf20Sopenharmony_ci
1238c2ecf20Sopenharmony_ci/**
1248c2ecf20Sopenharmony_ci * struct ishtp_device - ISHTP private device struct
1258c2ecf20Sopenharmony_ci */
1268c2ecf20Sopenharmony_cistruct ishtp_device {
1278c2ecf20Sopenharmony_ci	struct device *devc;	/* pointer to lowest device */
1288c2ecf20Sopenharmony_ci	struct pci_dev *pdev;	/* PCI device to get device ids */
1298c2ecf20Sopenharmony_ci
1308c2ecf20Sopenharmony_ci	/* waitq for waiting for suspend response */
1318c2ecf20Sopenharmony_ci	wait_queue_head_t suspend_wait;
1328c2ecf20Sopenharmony_ci	bool suspend_flag;	/* Suspend is active */
1338c2ecf20Sopenharmony_ci
1348c2ecf20Sopenharmony_ci	/* waitq for waiting for resume response */
1358c2ecf20Sopenharmony_ci	wait_queue_head_t resume_wait;
1368c2ecf20Sopenharmony_ci	bool resume_flag;	/*Resume is active */
1378c2ecf20Sopenharmony_ci
1388c2ecf20Sopenharmony_ci	/*
1398c2ecf20Sopenharmony_ci	 * lock for the device, for everything that doesn't have
1408c2ecf20Sopenharmony_ci	 * a dedicated spinlock
1418c2ecf20Sopenharmony_ci	 */
1428c2ecf20Sopenharmony_ci	spinlock_t device_lock;
1438c2ecf20Sopenharmony_ci
1448c2ecf20Sopenharmony_ci	bool recvd_hw_ready;
1458c2ecf20Sopenharmony_ci	struct hbm_version version;
1468c2ecf20Sopenharmony_ci	int transfer_path; /* Choice of transfer path: IPC or DMA */
1478c2ecf20Sopenharmony_ci
1488c2ecf20Sopenharmony_ci	/* ishtp device states */
1498c2ecf20Sopenharmony_ci	enum ishtp_dev_state dev_state;
1508c2ecf20Sopenharmony_ci	enum ishtp_hbm_state hbm_state;
1518c2ecf20Sopenharmony_ci
1528c2ecf20Sopenharmony_ci	/* driver read queue */
1538c2ecf20Sopenharmony_ci	struct ishtp_cl_rb read_list;
1548c2ecf20Sopenharmony_ci	spinlock_t read_list_spinlock;
1558c2ecf20Sopenharmony_ci
1568c2ecf20Sopenharmony_ci	/* list of ishtp_cl's */
1578c2ecf20Sopenharmony_ci	struct list_head cl_list;
1588c2ecf20Sopenharmony_ci	spinlock_t cl_list_lock;
1598c2ecf20Sopenharmony_ci	long open_handle_count;
1608c2ecf20Sopenharmony_ci
1618c2ecf20Sopenharmony_ci	/* List of bus devices */
1628c2ecf20Sopenharmony_ci	struct list_head device_list;
1638c2ecf20Sopenharmony_ci	spinlock_t device_list_lock;
1648c2ecf20Sopenharmony_ci
1658c2ecf20Sopenharmony_ci	/* waiting queues for receive message from FW */
1668c2ecf20Sopenharmony_ci	wait_queue_head_t wait_hw_ready;
1678c2ecf20Sopenharmony_ci	wait_queue_head_t wait_hbm_recvd_msg;
1688c2ecf20Sopenharmony_ci
1698c2ecf20Sopenharmony_ci	/* FIFO for input messages for BH processing */
1708c2ecf20Sopenharmony_ci	unsigned char rd_msg_fifo[RD_INT_FIFO_SIZE * IPC_PAYLOAD_SIZE];
1718c2ecf20Sopenharmony_ci	unsigned int rd_msg_fifo_head, rd_msg_fifo_tail;
1728c2ecf20Sopenharmony_ci	spinlock_t rd_msg_spinlock;
1738c2ecf20Sopenharmony_ci	struct work_struct bh_hbm_work;
1748c2ecf20Sopenharmony_ci
1758c2ecf20Sopenharmony_ci	/* IPC write queue */
1768c2ecf20Sopenharmony_ci	struct list_head wr_processing_list, wr_free_list;
1778c2ecf20Sopenharmony_ci	/* For both processing list  and free list */
1788c2ecf20Sopenharmony_ci	spinlock_t wr_processing_spinlock;
1798c2ecf20Sopenharmony_ci
1808c2ecf20Sopenharmony_ci	struct ishtp_fw_client *fw_clients; /*Note:memory has to be allocated*/
1818c2ecf20Sopenharmony_ci	DECLARE_BITMAP(fw_clients_map, ISHTP_CLIENTS_MAX);
1828c2ecf20Sopenharmony_ci	DECLARE_BITMAP(host_clients_map, ISHTP_CLIENTS_MAX);
1838c2ecf20Sopenharmony_ci	uint8_t fw_clients_num;
1848c2ecf20Sopenharmony_ci	uint8_t fw_client_presentation_num;
1858c2ecf20Sopenharmony_ci	uint8_t fw_client_index;
1868c2ecf20Sopenharmony_ci	spinlock_t fw_clients_lock;
1878c2ecf20Sopenharmony_ci
1888c2ecf20Sopenharmony_ci	/* TX DMA buffers and slots */
1898c2ecf20Sopenharmony_ci	int ishtp_host_dma_enabled;
1908c2ecf20Sopenharmony_ci	void *ishtp_host_dma_tx_buf;
1918c2ecf20Sopenharmony_ci	unsigned int ishtp_host_dma_tx_buf_size;
1928c2ecf20Sopenharmony_ci	uint64_t ishtp_host_dma_tx_buf_phys;
1938c2ecf20Sopenharmony_ci	int ishtp_dma_num_slots;
1948c2ecf20Sopenharmony_ci
1958c2ecf20Sopenharmony_ci	/* map of 4k blocks in Tx dma buf: 0-free, 1-used */
1968c2ecf20Sopenharmony_ci	uint8_t *ishtp_dma_tx_map;
1978c2ecf20Sopenharmony_ci	spinlock_t ishtp_dma_tx_lock;
1988c2ecf20Sopenharmony_ci
1998c2ecf20Sopenharmony_ci	/* RX DMA buffers and slots */
2008c2ecf20Sopenharmony_ci	void *ishtp_host_dma_rx_buf;
2018c2ecf20Sopenharmony_ci	unsigned int ishtp_host_dma_rx_buf_size;
2028c2ecf20Sopenharmony_ci	uint64_t ishtp_host_dma_rx_buf_phys;
2038c2ecf20Sopenharmony_ci
2048c2ecf20Sopenharmony_ci	/* Dump to trace buffers if enabled*/
2058c2ecf20Sopenharmony_ci	__printf(2, 3) void (*print_log)(struct ishtp_device *dev,
2068c2ecf20Sopenharmony_ci					 const char *format, ...);
2078c2ecf20Sopenharmony_ci
2088c2ecf20Sopenharmony_ci	/* Debug stats */
2098c2ecf20Sopenharmony_ci	unsigned int	ipc_rx_cnt;
2108c2ecf20Sopenharmony_ci	unsigned long long	ipc_rx_bytes_cnt;
2118c2ecf20Sopenharmony_ci	unsigned int	ipc_tx_cnt;
2128c2ecf20Sopenharmony_ci	unsigned long long	ipc_tx_bytes_cnt;
2138c2ecf20Sopenharmony_ci
2148c2ecf20Sopenharmony_ci	const struct ishtp_hw_ops *ops;
2158c2ecf20Sopenharmony_ci	size_t	mtu;
2168c2ecf20Sopenharmony_ci	uint32_t	ishtp_msg_hdr;
2178c2ecf20Sopenharmony_ci	char hw[] __aligned(sizeof(void *));
2188c2ecf20Sopenharmony_ci};
2198c2ecf20Sopenharmony_ci
2208c2ecf20Sopenharmony_cistatic inline unsigned long ishtp_secs_to_jiffies(unsigned long sec)
2218c2ecf20Sopenharmony_ci{
2228c2ecf20Sopenharmony_ci	return msecs_to_jiffies(sec * MSEC_PER_SEC);
2238c2ecf20Sopenharmony_ci}
2248c2ecf20Sopenharmony_ci
2258c2ecf20Sopenharmony_ci/*
2268c2ecf20Sopenharmony_ci * Register Access Function
2278c2ecf20Sopenharmony_ci */
2288c2ecf20Sopenharmony_cistatic inline int ish_ipc_reset(struct ishtp_device *dev)
2298c2ecf20Sopenharmony_ci{
2308c2ecf20Sopenharmony_ci	return dev->ops->ipc_reset(dev);
2318c2ecf20Sopenharmony_ci}
2328c2ecf20Sopenharmony_ci
2338c2ecf20Sopenharmony_ci/* Exported function */
2348c2ecf20Sopenharmony_civoid	ishtp_device_init(struct ishtp_device *dev);
2358c2ecf20Sopenharmony_ciint	ishtp_start(struct ishtp_device *dev);
2368c2ecf20Sopenharmony_ci
2378c2ecf20Sopenharmony_ci#endif /*_ISHTP_DEV_H_*/
238