162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only */ 262306a36Sopenharmony_ci/* 362306a36Sopenharmony_ci * Most ISHTP provider device and ISHTP logic declarations 462306a36Sopenharmony_ci * 562306a36Sopenharmony_ci * Copyright (c) 2003-2016, Intel Corporation. 662306a36Sopenharmony_ci */ 762306a36Sopenharmony_ci 862306a36Sopenharmony_ci#ifndef _ISHTP_DEV_H_ 962306a36Sopenharmony_ci#define _ISHTP_DEV_H_ 1062306a36Sopenharmony_ci 1162306a36Sopenharmony_ci#include <linux/types.h> 1262306a36Sopenharmony_ci#include <linux/spinlock.h> 1362306a36Sopenharmony_ci#include <linux/intel-ish-client-if.h> 1462306a36Sopenharmony_ci#include "bus.h" 1562306a36Sopenharmony_ci#include "hbm.h" 1662306a36Sopenharmony_ci 1762306a36Sopenharmony_ci#define IPC_PAYLOAD_SIZE 128 1862306a36Sopenharmony_ci#define ISHTP_RD_MSG_BUF_SIZE IPC_PAYLOAD_SIZE 1962306a36Sopenharmony_ci#define IPC_FULL_MSG_SIZE 132 2062306a36Sopenharmony_ci 2162306a36Sopenharmony_ci/* Number of messages to be held in ISR->BH FIFO */ 2262306a36Sopenharmony_ci#define RD_INT_FIFO_SIZE 64 2362306a36Sopenharmony_ci 2462306a36Sopenharmony_ci/* 2562306a36Sopenharmony_ci * Number of IPC messages to be held in Tx FIFO, to be sent by ISR - 2662306a36Sopenharmony_ci * Tx complete interrupt or RX_COMPLETE handler 2762306a36Sopenharmony_ci */ 2862306a36Sopenharmony_ci#define IPC_TX_FIFO_SIZE 512 2962306a36Sopenharmony_ci 3062306a36Sopenharmony_ci/* 3162306a36Sopenharmony_ci * Number of Maximum ISHTP Clients 3262306a36Sopenharmony_ci */ 3362306a36Sopenharmony_ci#define ISHTP_CLIENTS_MAX 256 3462306a36Sopenharmony_ci 3562306a36Sopenharmony_ci/* 3662306a36Sopenharmony_ci * Number of File descriptors/handles 3762306a36Sopenharmony_ci * that can be opened to the driver. 3862306a36Sopenharmony_ci * 3962306a36Sopenharmony_ci * Limit to 255: 256 Total Clients 4062306a36Sopenharmony_ci * minus internal client for ISHTP Bus Messages 4162306a36Sopenharmony_ci */ 4262306a36Sopenharmony_ci#define ISHTP_MAX_OPEN_HANDLE_COUNT (ISHTP_CLIENTS_MAX - 1) 4362306a36Sopenharmony_ci 4462306a36Sopenharmony_ci/* Internal Clients Number */ 4562306a36Sopenharmony_ci#define ISHTP_HOST_CLIENT_ID_ANY (-1) 4662306a36Sopenharmony_ci#define ISHTP_HBM_HOST_CLIENT_ID 0 4762306a36Sopenharmony_ci 4862306a36Sopenharmony_ci#define MAX_DMA_DELAY 20 4962306a36Sopenharmony_ci 5062306a36Sopenharmony_ci/* ISHTP device states */ 5162306a36Sopenharmony_cienum ishtp_dev_state { 5262306a36Sopenharmony_ci ISHTP_DEV_INITIALIZING = 0, 5362306a36Sopenharmony_ci ISHTP_DEV_INIT_CLIENTS, 5462306a36Sopenharmony_ci ISHTP_DEV_ENABLED, 5562306a36Sopenharmony_ci ISHTP_DEV_RESETTING, 5662306a36Sopenharmony_ci ISHTP_DEV_DISABLED, 5762306a36Sopenharmony_ci ISHTP_DEV_POWER_DOWN, 5862306a36Sopenharmony_ci ISHTP_DEV_POWER_UP 5962306a36Sopenharmony_ci}; 6062306a36Sopenharmony_ciconst char *ishtp_dev_state_str(int state); 6162306a36Sopenharmony_ci 6262306a36Sopenharmony_cistruct ishtp_cl; 6362306a36Sopenharmony_ci 6462306a36Sopenharmony_ci/** 6562306a36Sopenharmony_ci * struct ishtp_fw_client - representation of fw client 6662306a36Sopenharmony_ci * 6762306a36Sopenharmony_ci * @props - client properties 6862306a36Sopenharmony_ci * @client_id - fw client id 6962306a36Sopenharmony_ci */ 7062306a36Sopenharmony_cistruct ishtp_fw_client { 7162306a36Sopenharmony_ci struct ishtp_client_properties props; 7262306a36Sopenharmony_ci uint8_t client_id; 7362306a36Sopenharmony_ci}; 7462306a36Sopenharmony_ci 7562306a36Sopenharmony_ci/* 7662306a36Sopenharmony_ci * Control info for IPC messages ISHTP/IPC sending FIFO - 7762306a36Sopenharmony_ci * list with inline data buffer 7862306a36Sopenharmony_ci * This structure will be filled with parameters submitted 7962306a36Sopenharmony_ci * by the caller glue layer 8062306a36Sopenharmony_ci * 'buf' may be pointing to the external buffer or to 'inline_data' 8162306a36Sopenharmony_ci * 'offset' will be initialized to 0 by submitting 8262306a36Sopenharmony_ci * 8362306a36Sopenharmony_ci * 'ipc_send_compl' is intended for use by clients that send fragmented 8462306a36Sopenharmony_ci * messages. When a fragment is sent down to IPC msg regs, 8562306a36Sopenharmony_ci * it will be called. 8662306a36Sopenharmony_ci * If it has more fragments to send, it will do it. With last fragment 8762306a36Sopenharmony_ci * it will send appropriate ISHTP "message-complete" flag. 8862306a36Sopenharmony_ci * It will remove the outstanding message 8962306a36Sopenharmony_ci * (mark outstanding buffer as available). 9062306a36Sopenharmony_ci * If counting flow control is in work and there are more flow control 9162306a36Sopenharmony_ci * credits, it can put the next client message queued in cl. 9262306a36Sopenharmony_ci * structure for IPC processing. 9362306a36Sopenharmony_ci * 9462306a36Sopenharmony_ci */ 9562306a36Sopenharmony_cistruct wr_msg_ctl_info { 9662306a36Sopenharmony_ci /* Will be called with 'ipc_send_compl_prm' as parameter */ 9762306a36Sopenharmony_ci void (*ipc_send_compl)(void *); 9862306a36Sopenharmony_ci 9962306a36Sopenharmony_ci void *ipc_send_compl_prm; 10062306a36Sopenharmony_ci size_t length; 10162306a36Sopenharmony_ci struct list_head link; 10262306a36Sopenharmony_ci unsigned char inline_data[IPC_FULL_MSG_SIZE]; 10362306a36Sopenharmony_ci}; 10462306a36Sopenharmony_ci 10562306a36Sopenharmony_ci/* 10662306a36Sopenharmony_ci * The ISHTP layer talks to hardware IPC message using the following 10762306a36Sopenharmony_ci * callbacks 10862306a36Sopenharmony_ci */ 10962306a36Sopenharmony_cistruct ishtp_hw_ops { 11062306a36Sopenharmony_ci int (*hw_reset)(struct ishtp_device *dev); 11162306a36Sopenharmony_ci int (*ipc_reset)(struct ishtp_device *dev); 11262306a36Sopenharmony_ci uint32_t (*ipc_get_header)(struct ishtp_device *dev, int length, 11362306a36Sopenharmony_ci int busy); 11462306a36Sopenharmony_ci int (*write)(struct ishtp_device *dev, 11562306a36Sopenharmony_ci void (*ipc_send_compl)(void *), void *ipc_send_compl_prm, 11662306a36Sopenharmony_ci unsigned char *msg, int length); 11762306a36Sopenharmony_ci uint32_t (*ishtp_read_hdr)(const struct ishtp_device *dev); 11862306a36Sopenharmony_ci int (*ishtp_read)(struct ishtp_device *dev, unsigned char *buffer, 11962306a36Sopenharmony_ci unsigned long buffer_length); 12062306a36Sopenharmony_ci uint32_t (*get_fw_status)(struct ishtp_device *dev); 12162306a36Sopenharmony_ci void (*sync_fw_clock)(struct ishtp_device *dev); 12262306a36Sopenharmony_ci bool (*dma_no_cache_snooping)(struct ishtp_device *dev); 12362306a36Sopenharmony_ci}; 12462306a36Sopenharmony_ci 12562306a36Sopenharmony_ci/** 12662306a36Sopenharmony_ci * struct ishtp_device - ISHTP private device struct 12762306a36Sopenharmony_ci */ 12862306a36Sopenharmony_cistruct ishtp_device { 12962306a36Sopenharmony_ci struct device *devc; /* pointer to lowest device */ 13062306a36Sopenharmony_ci struct pci_dev *pdev; /* PCI device to get device ids */ 13162306a36Sopenharmony_ci 13262306a36Sopenharmony_ci /* waitq for waiting for suspend response */ 13362306a36Sopenharmony_ci wait_queue_head_t suspend_wait; 13462306a36Sopenharmony_ci bool suspend_flag; /* Suspend is active */ 13562306a36Sopenharmony_ci 13662306a36Sopenharmony_ci /* waitq for waiting for resume response */ 13762306a36Sopenharmony_ci wait_queue_head_t resume_wait; 13862306a36Sopenharmony_ci bool resume_flag; /*Resume is active */ 13962306a36Sopenharmony_ci 14062306a36Sopenharmony_ci /* 14162306a36Sopenharmony_ci * lock for the device, for everything that doesn't have 14262306a36Sopenharmony_ci * a dedicated spinlock 14362306a36Sopenharmony_ci */ 14462306a36Sopenharmony_ci spinlock_t device_lock; 14562306a36Sopenharmony_ci 14662306a36Sopenharmony_ci bool recvd_hw_ready; 14762306a36Sopenharmony_ci struct hbm_version version; 14862306a36Sopenharmony_ci int transfer_path; /* Choice of transfer path: IPC or DMA */ 14962306a36Sopenharmony_ci 15062306a36Sopenharmony_ci /* ishtp device states */ 15162306a36Sopenharmony_ci enum ishtp_dev_state dev_state; 15262306a36Sopenharmony_ci enum ishtp_hbm_state hbm_state; 15362306a36Sopenharmony_ci 15462306a36Sopenharmony_ci /* driver read queue */ 15562306a36Sopenharmony_ci struct ishtp_cl_rb read_list; 15662306a36Sopenharmony_ci spinlock_t read_list_spinlock; 15762306a36Sopenharmony_ci 15862306a36Sopenharmony_ci /* list of ishtp_cl's */ 15962306a36Sopenharmony_ci struct list_head cl_list; 16062306a36Sopenharmony_ci spinlock_t cl_list_lock; 16162306a36Sopenharmony_ci long open_handle_count; 16262306a36Sopenharmony_ci 16362306a36Sopenharmony_ci /* List of bus devices */ 16462306a36Sopenharmony_ci struct list_head device_list; 16562306a36Sopenharmony_ci spinlock_t device_list_lock; 16662306a36Sopenharmony_ci 16762306a36Sopenharmony_ci /* waiting queues for receive message from FW */ 16862306a36Sopenharmony_ci wait_queue_head_t wait_hw_ready; 16962306a36Sopenharmony_ci wait_queue_head_t wait_hbm_recvd_msg; 17062306a36Sopenharmony_ci 17162306a36Sopenharmony_ci /* FIFO for input messages for BH processing */ 17262306a36Sopenharmony_ci unsigned char rd_msg_fifo[RD_INT_FIFO_SIZE * IPC_PAYLOAD_SIZE]; 17362306a36Sopenharmony_ci unsigned int rd_msg_fifo_head, rd_msg_fifo_tail; 17462306a36Sopenharmony_ci spinlock_t rd_msg_spinlock; 17562306a36Sopenharmony_ci struct work_struct bh_hbm_work; 17662306a36Sopenharmony_ci 17762306a36Sopenharmony_ci /* IPC write queue */ 17862306a36Sopenharmony_ci struct list_head wr_processing_list, wr_free_list; 17962306a36Sopenharmony_ci /* For both processing list and free list */ 18062306a36Sopenharmony_ci spinlock_t wr_processing_spinlock; 18162306a36Sopenharmony_ci 18262306a36Sopenharmony_ci struct ishtp_fw_client *fw_clients; /*Note:memory has to be allocated*/ 18362306a36Sopenharmony_ci DECLARE_BITMAP(fw_clients_map, ISHTP_CLIENTS_MAX); 18462306a36Sopenharmony_ci DECLARE_BITMAP(host_clients_map, ISHTP_CLIENTS_MAX); 18562306a36Sopenharmony_ci uint8_t fw_clients_num; 18662306a36Sopenharmony_ci uint8_t fw_client_presentation_num; 18762306a36Sopenharmony_ci uint8_t fw_client_index; 18862306a36Sopenharmony_ci spinlock_t fw_clients_lock; 18962306a36Sopenharmony_ci 19062306a36Sopenharmony_ci /* TX DMA buffers and slots */ 19162306a36Sopenharmony_ci int ishtp_host_dma_enabled; 19262306a36Sopenharmony_ci void *ishtp_host_dma_tx_buf; 19362306a36Sopenharmony_ci unsigned int ishtp_host_dma_tx_buf_size; 19462306a36Sopenharmony_ci uint64_t ishtp_host_dma_tx_buf_phys; 19562306a36Sopenharmony_ci int ishtp_dma_num_slots; 19662306a36Sopenharmony_ci 19762306a36Sopenharmony_ci /* map of 4k blocks in Tx dma buf: 0-free, 1-used */ 19862306a36Sopenharmony_ci uint8_t *ishtp_dma_tx_map; 19962306a36Sopenharmony_ci spinlock_t ishtp_dma_tx_lock; 20062306a36Sopenharmony_ci 20162306a36Sopenharmony_ci /* RX DMA buffers and slots */ 20262306a36Sopenharmony_ci void *ishtp_host_dma_rx_buf; 20362306a36Sopenharmony_ci unsigned int ishtp_host_dma_rx_buf_size; 20462306a36Sopenharmony_ci uint64_t ishtp_host_dma_rx_buf_phys; 20562306a36Sopenharmony_ci 20662306a36Sopenharmony_ci /* Dump to trace buffers if enabled*/ 20762306a36Sopenharmony_ci ishtp_print_log print_log; 20862306a36Sopenharmony_ci 20962306a36Sopenharmony_ci /* Debug stats */ 21062306a36Sopenharmony_ci unsigned int ipc_rx_cnt; 21162306a36Sopenharmony_ci unsigned long long ipc_rx_bytes_cnt; 21262306a36Sopenharmony_ci unsigned int ipc_tx_cnt; 21362306a36Sopenharmony_ci unsigned long long ipc_tx_bytes_cnt; 21462306a36Sopenharmony_ci 21562306a36Sopenharmony_ci const struct ishtp_hw_ops *ops; 21662306a36Sopenharmony_ci size_t mtu; 21762306a36Sopenharmony_ci uint32_t ishtp_msg_hdr; 21862306a36Sopenharmony_ci char hw[] __aligned(sizeof(void *)); 21962306a36Sopenharmony_ci}; 22062306a36Sopenharmony_ci 22162306a36Sopenharmony_cistatic inline unsigned long ishtp_secs_to_jiffies(unsigned long sec) 22262306a36Sopenharmony_ci{ 22362306a36Sopenharmony_ci return msecs_to_jiffies(sec * MSEC_PER_SEC); 22462306a36Sopenharmony_ci} 22562306a36Sopenharmony_ci 22662306a36Sopenharmony_ci/* 22762306a36Sopenharmony_ci * Register Access Function 22862306a36Sopenharmony_ci */ 22962306a36Sopenharmony_cistatic inline int ish_ipc_reset(struct ishtp_device *dev) 23062306a36Sopenharmony_ci{ 23162306a36Sopenharmony_ci return dev->ops->ipc_reset(dev); 23262306a36Sopenharmony_ci} 23362306a36Sopenharmony_ci 23462306a36Sopenharmony_ci/* Exported function */ 23562306a36Sopenharmony_civoid ishtp_device_init(struct ishtp_device *dev); 23662306a36Sopenharmony_ciint ishtp_start(struct ishtp_device *dev); 23762306a36Sopenharmony_ci 23862306a36Sopenharmony_ci#endif /*_ISHTP_DEV_H_*/ 239