| /* 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; |
| phys_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 |