238 lines
7.5 KiB
C
238 lines
7.5 KiB
C
/* SPDX-License-Identifier: GPL-2.0-only
|
|
*
|
|
* Copyright (C) 2020-21 Intel Corporation.
|
|
*/
|
|
|
|
#ifndef IOSM_IPC_PROTOCOL_H
|
|
#define IOSM_IPC_PROTOCOL_H
|
|
|
|
#include "iosm_ipc_imem.h"
|
|
#include "iosm_ipc_pm.h"
|
|
#include "iosm_ipc_protocol_ops.h"
|
|
|
|
/* Trigger the doorbell interrupt on CP. */
|
|
#define IPC_DOORBELL_IRQ_HPDA 0
|
|
#define IPC_DOORBELL_IRQ_IPC 1
|
|
#define IPC_DOORBELL_IRQ_SLEEP 2
|
|
|
|
/* IRQ vector number. */
|
|
#define IPC_DEVICE_IRQ_VECTOR 0
|
|
#define IPC_MSG_IRQ_VECTOR 0
|
|
#define IPC_UL_PIPE_IRQ_VECTOR 0
|
|
#define IPC_DL_PIPE_IRQ_VECTOR 0
|
|
|
|
#define IPC_MEM_MSG_ENTRIES 128
|
|
|
|
/* Default time out for sending IPC messages like open pipe, close pipe etc.
|
|
* during run mode.
|
|
*
|
|
* If the message interface lock to CP times out, the link to CP is broken.
|
|
* mode : run mode (IPC_MEM_EXEC_STAGE_RUN)
|
|
* unit : milliseconds
|
|
*/
|
|
#define IPC_MSG_COMPLETE_RUN_DEFAULT_TIMEOUT 500 /* 0.5 seconds */
|
|
|
|
/* Default time out for sending IPC messages like open pipe, close pipe etc.
|
|
* during boot mode.
|
|
*
|
|
* If the message interface lock to CP times out, the link to CP is broken.
|
|
* mode : boot mode
|
|
* (IPC_MEM_EXEC_STAGE_BOOT | IPC_MEM_EXEC_STAGE_PSI | IPC_MEM_EXEC_STAGE_EBL)
|
|
* unit : milliseconds
|
|
*/
|
|
#define IPC_MSG_COMPLETE_BOOT_DEFAULT_TIMEOUT 500 /* 0.5 seconds */
|
|
|
|
/**
|
|
* struct ipc_protocol_context_info - Structure of the context info
|
|
* @device_info_addr: 64 bit address to device info
|
|
* @head_array: 64 bit address to head pointer arr for the pipes
|
|
* @tail_array: 64 bit address to tail pointer arr for the pipes
|
|
* @msg_head: 64 bit address to message head pointer
|
|
* @msg_tail: 64 bit address to message tail pointer
|
|
* @msg_ring_addr: 64 bit pointer to the message ring buffer
|
|
* @msg_ring_entries: This field provides the number of entries which
|
|
* the MR can hold
|
|
* @msg_irq_vector: This field provides the IRQ which shall be
|
|
* generated by the EP device when generating
|
|
* completion for Messages.
|
|
* @device_info_irq_vector: This field provides the IRQ which shall be
|
|
* generated by the EP dev after updating Dev. Info
|
|
*/
|
|
struct ipc_protocol_context_info {
|
|
phys_addr_t device_info_addr;
|
|
phys_addr_t head_array;
|
|
phys_addr_t tail_array;
|
|
phys_addr_t msg_head;
|
|
phys_addr_t msg_tail;
|
|
phys_addr_t msg_ring_addr;
|
|
__le16 msg_ring_entries;
|
|
u8 msg_irq_vector;
|
|
u8 device_info_irq_vector;
|
|
};
|
|
|
|
/**
|
|
* struct ipc_protocol_device_info - Structure for the device information
|
|
* @execution_stage: CP execution stage
|
|
* @ipc_status: IPC states
|
|
* @device_sleep_notification: Requested device pm states
|
|
*/
|
|
struct ipc_protocol_device_info {
|
|
__le32 execution_stage;
|
|
__le32 ipc_status;
|
|
__le32 device_sleep_notification;
|
|
};
|
|
|
|
/**
|
|
* struct ipc_protocol_ap_shm - Protocol Shared Memory Structure
|
|
* @ci: Context information struct
|
|
* @device_info: Device information struct
|
|
* @msg_head: Point to msg head
|
|
* @head_array: Array of head pointer
|
|
* @msg_tail: Point to msg tail
|
|
* @tail_array: Array of tail pointer
|
|
* @msg_ring: Circular buffers for the read/tail and write/head
|
|
* indeces.
|
|
*/
|
|
struct ipc_protocol_ap_shm {
|
|
struct ipc_protocol_context_info ci;
|
|
struct ipc_protocol_device_info device_info;
|
|
__le32 msg_head;
|
|
__le32 head_array[IPC_MEM_MAX_PIPES];
|
|
__le32 msg_tail;
|
|
__le32 tail_array[IPC_MEM_MAX_PIPES];
|
|
union ipc_mem_msg_entry msg_ring[IPC_MEM_MSG_ENTRIES];
|
|
};
|
|
|
|
/**
|
|
* struct iosm_protocol - Structure for IPC protocol.
|
|
* @p_ap_shm: Pointer to Protocol Shared Memory Structure
|
|
* @pm: Instance to struct iosm_pm
|
|
* @pcie: Pointer to struct iosm_pcie
|
|
* @imem: Pointer to struct iosm_imem
|
|
* @rsp_ring: Array of OS completion objects to be triggered once CP
|
|
* acknowledges a request in the message ring
|
|
* @dev: Pointer to device structure
|
|
* @phy_ap_shm: Physical/Mapped representation of the shared memory info
|
|
* @old_msg_tail: Old msg tail ptr, until AP has handled ACK's from CP
|
|
*/
|
|
struct iosm_protocol {
|
|
struct ipc_protocol_ap_shm *p_ap_shm;
|
|
struct iosm_pm pm;
|
|
struct iosm_pcie *pcie;
|
|
struct iosm_imem *imem;
|
|
struct ipc_rsp *rsp_ring[IPC_MEM_MSG_ENTRIES];
|
|
struct device *dev;
|
|
dma_addr_t phy_ap_shm;
|
|
u32 old_msg_tail;
|
|
};
|
|
|
|
/**
|
|
* struct ipc_call_msg_send_args - Structure for message argument for
|
|
* tasklet function.
|
|
* @prep_args: Arguments for message preparation function
|
|
* @response: Can be NULL if result can be ignored
|
|
* @msg_type: Message Type
|
|
*/
|
|
struct ipc_call_msg_send_args {
|
|
union ipc_msg_prep_args *prep_args;
|
|
struct ipc_rsp *response;
|
|
enum ipc_msg_prep_type msg_type;
|
|
};
|
|
|
|
/**
|
|
* ipc_protocol_tq_msg_send - prepare the msg and send to CP
|
|
* @ipc_protocol: Pointer to ipc_protocol instance
|
|
* @msg_type: Message type
|
|
* @prep_args: Message arguments
|
|
* @response: Pointer to a response object which has a
|
|
* completion object and return code.
|
|
*
|
|
* Returns: 0 on success and failure value on error
|
|
*/
|
|
int ipc_protocol_tq_msg_send(struct iosm_protocol *ipc_protocol,
|
|
enum ipc_msg_prep_type msg_type,
|
|
union ipc_msg_prep_args *prep_args,
|
|
struct ipc_rsp *response);
|
|
|
|
/**
|
|
* ipc_protocol_msg_send - Send ipc control message to CP and wait for response
|
|
* @ipc_protocol: Pointer to ipc_protocol instance
|
|
* @prep: Message type
|
|
* @prep_args: Message arguments
|
|
*
|
|
* Returns: 0 on success and failure value on error
|
|
*/
|
|
int ipc_protocol_msg_send(struct iosm_protocol *ipc_protocol,
|
|
enum ipc_msg_prep_type prep,
|
|
union ipc_msg_prep_args *prep_args);
|
|
|
|
/**
|
|
* ipc_protocol_suspend - Signal to CP that host wants to go to sleep (suspend).
|
|
* @ipc_protocol: Pointer to ipc_protocol instance
|
|
*
|
|
* Returns: true if host can suspend, false if suspend must be aborted.
|
|
*/
|
|
bool ipc_protocol_suspend(struct iosm_protocol *ipc_protocol);
|
|
|
|
/**
|
|
* ipc_protocol_s2idle_sleep - Call PM function to set PM variables in s2idle
|
|
* sleep/active case
|
|
* @ipc_protocol: Pointer to ipc_protocol instance
|
|
* @sleep: True for sleep/False for active
|
|
*/
|
|
void ipc_protocol_s2idle_sleep(struct iosm_protocol *ipc_protocol, bool sleep);
|
|
|
|
/**
|
|
* ipc_protocol_resume - Signal to CP that host wants to resume operation.
|
|
* @ipc_protocol: Pointer to ipc_protocol instance
|
|
*
|
|
* Returns: true if host can resume, false if there is a problem.
|
|
*/
|
|
bool ipc_protocol_resume(struct iosm_protocol *ipc_protocol);
|
|
|
|
/**
|
|
* ipc_protocol_pm_dev_sleep_handle - Handles the Device Sleep state change
|
|
* notification.
|
|
* @ipc_protocol: Pointer to ipc_protocol instance.
|
|
*
|
|
* Returns: true if sleep notification handled, false otherwise.
|
|
*/
|
|
bool ipc_protocol_pm_dev_sleep_handle(struct iosm_protocol *ipc_protocol);
|
|
|
|
/**
|
|
* ipc_protocol_doorbell_trigger - Wrapper for PM function which wake up the
|
|
* device if it is in low power mode
|
|
* and trigger a head pointer update interrupt.
|
|
* @ipc_protocol: Pointer to ipc_protocol instance.
|
|
* @identifier: Specifies what component triggered hpda
|
|
* update irq
|
|
*/
|
|
void ipc_protocol_doorbell_trigger(struct iosm_protocol *ipc_protocol,
|
|
u32 identifier);
|
|
|
|
/**
|
|
* ipc_protocol_sleep_notification_string - Returns last Sleep Notification as
|
|
* string.
|
|
* @ipc_protocol: Instance pointer of Protocol module.
|
|
*
|
|
* Returns: Pointer to string.
|
|
*/
|
|
const char *
|
|
ipc_protocol_sleep_notification_string(struct iosm_protocol *ipc_protocol);
|
|
|
|
/**
|
|
* ipc_protocol_init - Allocates IPC protocol instance
|
|
* @ipc_imem: Pointer to iosm_imem structure
|
|
*
|
|
* Returns: Address of IPC protocol instance on success & NULL on failure.
|
|
*/
|
|
struct iosm_protocol *ipc_protocol_init(struct iosm_imem *ipc_imem);
|
|
|
|
/**
|
|
* ipc_protocol_deinit - Deallocates IPC protocol instance
|
|
* @ipc_protocol: pointer to the IPC protocol instance
|
|
*/
|
|
void ipc_protocol_deinit(struct iosm_protocol *ipc_protocol);
|
|
|
|
#endif
|