162306a36Sopenharmony_ci/* SPDX-License-Identifier: GPL-2.0-only
262306a36Sopenharmony_ci *
362306a36Sopenharmony_ci * Copyright (C) 2020-21 Intel Corporation.
462306a36Sopenharmony_ci */
562306a36Sopenharmony_ci
662306a36Sopenharmony_ci#ifndef IOSM_IPC_PROTOCOL_H
762306a36Sopenharmony_ci#define IOSM_IPC_PROTOCOL_H
862306a36Sopenharmony_ci
962306a36Sopenharmony_ci#include "iosm_ipc_imem.h"
1062306a36Sopenharmony_ci#include "iosm_ipc_pm.h"
1162306a36Sopenharmony_ci#include "iosm_ipc_protocol_ops.h"
1262306a36Sopenharmony_ci
1362306a36Sopenharmony_ci/* Trigger the doorbell interrupt on CP. */
1462306a36Sopenharmony_ci#define IPC_DOORBELL_IRQ_HPDA 0
1562306a36Sopenharmony_ci#define IPC_DOORBELL_IRQ_IPC 1
1662306a36Sopenharmony_ci#define IPC_DOORBELL_IRQ_SLEEP 2
1762306a36Sopenharmony_ci
1862306a36Sopenharmony_ci/* IRQ vector number. */
1962306a36Sopenharmony_ci#define IPC_DEVICE_IRQ_VECTOR 0
2062306a36Sopenharmony_ci#define IPC_MSG_IRQ_VECTOR 0
2162306a36Sopenharmony_ci#define IPC_UL_PIPE_IRQ_VECTOR 0
2262306a36Sopenharmony_ci#define IPC_DL_PIPE_IRQ_VECTOR 0
2362306a36Sopenharmony_ci
2462306a36Sopenharmony_ci#define IPC_MEM_MSG_ENTRIES 128
2562306a36Sopenharmony_ci
2662306a36Sopenharmony_ci/* Default time out for sending IPC messages like open pipe, close pipe etc.
2762306a36Sopenharmony_ci * during run mode.
2862306a36Sopenharmony_ci *
2962306a36Sopenharmony_ci * If the message interface lock to CP times out, the link to CP is broken.
3062306a36Sopenharmony_ci * mode : run mode (IPC_MEM_EXEC_STAGE_RUN)
3162306a36Sopenharmony_ci * unit : milliseconds
3262306a36Sopenharmony_ci */
3362306a36Sopenharmony_ci#define IPC_MSG_COMPLETE_RUN_DEFAULT_TIMEOUT 500 /* 0.5 seconds */
3462306a36Sopenharmony_ci
3562306a36Sopenharmony_ci/* Default time out for sending IPC messages like open pipe, close pipe etc.
3662306a36Sopenharmony_ci * during boot mode.
3762306a36Sopenharmony_ci *
3862306a36Sopenharmony_ci * If the message interface lock to CP times out, the link to CP is broken.
3962306a36Sopenharmony_ci * mode : boot mode
4062306a36Sopenharmony_ci * (IPC_MEM_EXEC_STAGE_BOOT | IPC_MEM_EXEC_STAGE_PSI | IPC_MEM_EXEC_STAGE_EBL)
4162306a36Sopenharmony_ci * unit : milliseconds
4262306a36Sopenharmony_ci */
4362306a36Sopenharmony_ci#define IPC_MSG_COMPLETE_BOOT_DEFAULT_TIMEOUT 500 /* 0.5 seconds */
4462306a36Sopenharmony_ci
4562306a36Sopenharmony_ci/**
4662306a36Sopenharmony_ci * struct ipc_protocol_context_info - Structure of the context info
4762306a36Sopenharmony_ci * @device_info_addr:		64 bit address to device info
4862306a36Sopenharmony_ci * @head_array:			64 bit address to head pointer arr for the pipes
4962306a36Sopenharmony_ci * @tail_array:			64 bit address to tail pointer arr for the pipes
5062306a36Sopenharmony_ci * @msg_head:			64 bit address to message head pointer
5162306a36Sopenharmony_ci * @msg_tail:			64 bit address to message tail pointer
5262306a36Sopenharmony_ci * @msg_ring_addr:		64 bit pointer to the message ring buffer
5362306a36Sopenharmony_ci * @msg_ring_entries:		This field provides the number of entries which
5462306a36Sopenharmony_ci *				the MR can hold
5562306a36Sopenharmony_ci * @msg_irq_vector:		This field provides the IRQ which shall be
5662306a36Sopenharmony_ci *				generated by the EP device when generating
5762306a36Sopenharmony_ci *				completion for Messages.
5862306a36Sopenharmony_ci * @device_info_irq_vector:	This field provides the IRQ which shall be
5962306a36Sopenharmony_ci *				generated by the EP dev after updating Dev. Info
6062306a36Sopenharmony_ci */
6162306a36Sopenharmony_cistruct ipc_protocol_context_info {
6262306a36Sopenharmony_ci	phys_addr_t device_info_addr;
6362306a36Sopenharmony_ci	phys_addr_t head_array;
6462306a36Sopenharmony_ci	phys_addr_t tail_array;
6562306a36Sopenharmony_ci	phys_addr_t msg_head;
6662306a36Sopenharmony_ci	phys_addr_t msg_tail;
6762306a36Sopenharmony_ci	phys_addr_t msg_ring_addr;
6862306a36Sopenharmony_ci	__le16 msg_ring_entries;
6962306a36Sopenharmony_ci	u8 msg_irq_vector;
7062306a36Sopenharmony_ci	u8 device_info_irq_vector;
7162306a36Sopenharmony_ci};
7262306a36Sopenharmony_ci
7362306a36Sopenharmony_ci/**
7462306a36Sopenharmony_ci * struct ipc_protocol_device_info - Structure for the device information
7562306a36Sopenharmony_ci * @execution_stage:		CP execution stage
7662306a36Sopenharmony_ci * @ipc_status:			IPC states
7762306a36Sopenharmony_ci * @device_sleep_notification:	Requested device pm states
7862306a36Sopenharmony_ci */
7962306a36Sopenharmony_cistruct ipc_protocol_device_info {
8062306a36Sopenharmony_ci	__le32 execution_stage;
8162306a36Sopenharmony_ci	__le32 ipc_status;
8262306a36Sopenharmony_ci	__le32 device_sleep_notification;
8362306a36Sopenharmony_ci};
8462306a36Sopenharmony_ci
8562306a36Sopenharmony_ci/**
8662306a36Sopenharmony_ci * struct ipc_protocol_ap_shm - Protocol Shared Memory Structure
8762306a36Sopenharmony_ci * @ci:			Context information struct
8862306a36Sopenharmony_ci * @device_info:	Device information struct
8962306a36Sopenharmony_ci * @msg_head:		Point to msg head
9062306a36Sopenharmony_ci * @head_array:		Array of head pointer
9162306a36Sopenharmony_ci * @msg_tail:		Point to msg tail
9262306a36Sopenharmony_ci * @tail_array:		Array of tail pointer
9362306a36Sopenharmony_ci * @msg_ring:		Circular buffers for the read/tail and write/head
9462306a36Sopenharmony_ci *			indeces.
9562306a36Sopenharmony_ci */
9662306a36Sopenharmony_cistruct ipc_protocol_ap_shm {
9762306a36Sopenharmony_ci	struct ipc_protocol_context_info ci;
9862306a36Sopenharmony_ci	struct ipc_protocol_device_info device_info;
9962306a36Sopenharmony_ci	__le32 msg_head;
10062306a36Sopenharmony_ci	__le32 head_array[IPC_MEM_MAX_PIPES];
10162306a36Sopenharmony_ci	__le32 msg_tail;
10262306a36Sopenharmony_ci	__le32 tail_array[IPC_MEM_MAX_PIPES];
10362306a36Sopenharmony_ci	union ipc_mem_msg_entry msg_ring[IPC_MEM_MSG_ENTRIES];
10462306a36Sopenharmony_ci};
10562306a36Sopenharmony_ci
10662306a36Sopenharmony_ci/**
10762306a36Sopenharmony_ci * struct iosm_protocol - Structure for IPC protocol.
10862306a36Sopenharmony_ci * @p_ap_shm:		Pointer to Protocol Shared Memory Structure
10962306a36Sopenharmony_ci * @pm:			Instance to struct iosm_pm
11062306a36Sopenharmony_ci * @pcie:		Pointer to struct iosm_pcie
11162306a36Sopenharmony_ci * @imem:		Pointer to struct iosm_imem
11262306a36Sopenharmony_ci * @rsp_ring:		Array of OS completion objects to be triggered once CP
11362306a36Sopenharmony_ci *			acknowledges a request in the message ring
11462306a36Sopenharmony_ci * @dev:		Pointer to device structure
11562306a36Sopenharmony_ci * @phy_ap_shm:		Physical/Mapped representation of the shared memory info
11662306a36Sopenharmony_ci * @old_msg_tail:	Old msg tail ptr, until AP has handled ACK's from CP
11762306a36Sopenharmony_ci */
11862306a36Sopenharmony_cistruct iosm_protocol {
11962306a36Sopenharmony_ci	struct ipc_protocol_ap_shm *p_ap_shm;
12062306a36Sopenharmony_ci	struct iosm_pm pm;
12162306a36Sopenharmony_ci	struct iosm_pcie *pcie;
12262306a36Sopenharmony_ci	struct iosm_imem *imem;
12362306a36Sopenharmony_ci	struct ipc_rsp *rsp_ring[IPC_MEM_MSG_ENTRIES];
12462306a36Sopenharmony_ci	struct device *dev;
12562306a36Sopenharmony_ci	dma_addr_t phy_ap_shm;
12662306a36Sopenharmony_ci	u32 old_msg_tail;
12762306a36Sopenharmony_ci};
12862306a36Sopenharmony_ci
12962306a36Sopenharmony_ci/**
13062306a36Sopenharmony_ci * struct ipc_call_msg_send_args - Structure for message argument for
13162306a36Sopenharmony_ci *				   tasklet function.
13262306a36Sopenharmony_ci * @prep_args:		Arguments for message preparation function
13362306a36Sopenharmony_ci * @response:		Can be NULL if result can be ignored
13462306a36Sopenharmony_ci * @msg_type:		Message Type
13562306a36Sopenharmony_ci */
13662306a36Sopenharmony_cistruct ipc_call_msg_send_args {
13762306a36Sopenharmony_ci	union ipc_msg_prep_args *prep_args;
13862306a36Sopenharmony_ci	struct ipc_rsp *response;
13962306a36Sopenharmony_ci	enum ipc_msg_prep_type msg_type;
14062306a36Sopenharmony_ci};
14162306a36Sopenharmony_ci
14262306a36Sopenharmony_ci/**
14362306a36Sopenharmony_ci * ipc_protocol_tq_msg_send - prepare the msg and send to CP
14462306a36Sopenharmony_ci * @ipc_protocol:	Pointer to ipc_protocol instance
14562306a36Sopenharmony_ci * @msg_type:		Message type
14662306a36Sopenharmony_ci * @prep_args:		Message arguments
14762306a36Sopenharmony_ci * @response:		Pointer to a response object which has a
14862306a36Sopenharmony_ci *			completion object and return code.
14962306a36Sopenharmony_ci *
15062306a36Sopenharmony_ci * Returns: 0 on success and failure value on error
15162306a36Sopenharmony_ci */
15262306a36Sopenharmony_ciint ipc_protocol_tq_msg_send(struct iosm_protocol *ipc_protocol,
15362306a36Sopenharmony_ci			     enum ipc_msg_prep_type msg_type,
15462306a36Sopenharmony_ci			     union ipc_msg_prep_args *prep_args,
15562306a36Sopenharmony_ci			     struct ipc_rsp *response);
15662306a36Sopenharmony_ci
15762306a36Sopenharmony_ci/**
15862306a36Sopenharmony_ci * ipc_protocol_msg_send - Send ipc control message to CP and wait for response
15962306a36Sopenharmony_ci * @ipc_protocol:	Pointer to ipc_protocol instance
16062306a36Sopenharmony_ci * @prep:		Message type
16162306a36Sopenharmony_ci * @prep_args:		Message arguments
16262306a36Sopenharmony_ci *
16362306a36Sopenharmony_ci * Returns: 0 on success and failure value on error
16462306a36Sopenharmony_ci */
16562306a36Sopenharmony_ciint ipc_protocol_msg_send(struct iosm_protocol *ipc_protocol,
16662306a36Sopenharmony_ci			  enum ipc_msg_prep_type prep,
16762306a36Sopenharmony_ci			  union ipc_msg_prep_args *prep_args);
16862306a36Sopenharmony_ci
16962306a36Sopenharmony_ci/**
17062306a36Sopenharmony_ci * ipc_protocol_suspend - Signal to CP that host wants to go to sleep (suspend).
17162306a36Sopenharmony_ci * @ipc_protocol:	Pointer to ipc_protocol instance
17262306a36Sopenharmony_ci *
17362306a36Sopenharmony_ci * Returns: true if host can suspend, false if suspend must be aborted.
17462306a36Sopenharmony_ci */
17562306a36Sopenharmony_cibool ipc_protocol_suspend(struct iosm_protocol *ipc_protocol);
17662306a36Sopenharmony_ci
17762306a36Sopenharmony_ci/**
17862306a36Sopenharmony_ci * ipc_protocol_s2idle_sleep - Call PM function to set PM variables in s2idle
17962306a36Sopenharmony_ci *			       sleep/active case
18062306a36Sopenharmony_ci * @ipc_protocol:	Pointer to ipc_protocol instance
18162306a36Sopenharmony_ci * @sleep:		True for sleep/False for active
18262306a36Sopenharmony_ci */
18362306a36Sopenharmony_civoid ipc_protocol_s2idle_sleep(struct iosm_protocol *ipc_protocol, bool sleep);
18462306a36Sopenharmony_ci
18562306a36Sopenharmony_ci/**
18662306a36Sopenharmony_ci * ipc_protocol_resume - Signal to CP that host wants to resume operation.
18762306a36Sopenharmony_ci * @ipc_protocol:	Pointer to ipc_protocol instance
18862306a36Sopenharmony_ci *
18962306a36Sopenharmony_ci * Returns: true if host can resume, false if there is a problem.
19062306a36Sopenharmony_ci */
19162306a36Sopenharmony_cibool ipc_protocol_resume(struct iosm_protocol *ipc_protocol);
19262306a36Sopenharmony_ci
19362306a36Sopenharmony_ci/**
19462306a36Sopenharmony_ci * ipc_protocol_pm_dev_sleep_handle - Handles the Device Sleep state change
19562306a36Sopenharmony_ci *				      notification.
19662306a36Sopenharmony_ci * @ipc_protocol:	Pointer to ipc_protocol instance.
19762306a36Sopenharmony_ci *
19862306a36Sopenharmony_ci * Returns: true if sleep notification handled, false otherwise.
19962306a36Sopenharmony_ci */
20062306a36Sopenharmony_cibool ipc_protocol_pm_dev_sleep_handle(struct iosm_protocol *ipc_protocol);
20162306a36Sopenharmony_ci
20262306a36Sopenharmony_ci/**
20362306a36Sopenharmony_ci * ipc_protocol_doorbell_trigger - Wrapper for PM function which wake up the
20462306a36Sopenharmony_ci *				   device if it is in low power mode
20562306a36Sopenharmony_ci *				   and trigger a head pointer update interrupt.
20662306a36Sopenharmony_ci * @ipc_protocol:	Pointer to ipc_protocol instance.
20762306a36Sopenharmony_ci * @identifier:		Specifies what component triggered hpda
20862306a36Sopenharmony_ci *			update irq
20962306a36Sopenharmony_ci */
21062306a36Sopenharmony_civoid ipc_protocol_doorbell_trigger(struct iosm_protocol *ipc_protocol,
21162306a36Sopenharmony_ci				   u32 identifier);
21262306a36Sopenharmony_ci
21362306a36Sopenharmony_ci/**
21462306a36Sopenharmony_ci * ipc_protocol_sleep_notification_string - Returns last Sleep Notification as
21562306a36Sopenharmony_ci *					    string.
21662306a36Sopenharmony_ci * @ipc_protocol:	Instance pointer of Protocol module.
21762306a36Sopenharmony_ci *
21862306a36Sopenharmony_ci * Returns: Pointer to string.
21962306a36Sopenharmony_ci */
22062306a36Sopenharmony_ciconst char *
22162306a36Sopenharmony_ciipc_protocol_sleep_notification_string(struct iosm_protocol *ipc_protocol);
22262306a36Sopenharmony_ci
22362306a36Sopenharmony_ci/**
22462306a36Sopenharmony_ci * ipc_protocol_init - Allocates IPC protocol instance
22562306a36Sopenharmony_ci * @ipc_imem:		Pointer to iosm_imem structure
22662306a36Sopenharmony_ci *
22762306a36Sopenharmony_ci * Returns: Address of IPC  protocol instance on success & NULL on failure.
22862306a36Sopenharmony_ci */
22962306a36Sopenharmony_cistruct iosm_protocol *ipc_protocol_init(struct iosm_imem *ipc_imem);
23062306a36Sopenharmony_ci
23162306a36Sopenharmony_ci/**
23262306a36Sopenharmony_ci * ipc_protocol_deinit - Deallocates IPC protocol instance
23362306a36Sopenharmony_ci * @ipc_protocol:	pointer to the IPC protocol instance
23462306a36Sopenharmony_ci */
23562306a36Sopenharmony_civoid ipc_protocol_deinit(struct iosm_protocol *ipc_protocol);
23662306a36Sopenharmony_ci
23762306a36Sopenharmony_ci#endif
238