0001
0002
0003
0004
0005
0006 #include "iosm_ipc_imem.h"
0007 #include "iosm_ipc_protocol.h"
0008 #include "iosm_ipc_protocol_ops.h"
0009 #include "iosm_ipc_pm.h"
0010 #include "iosm_ipc_task_queue.h"
0011
0012 int ipc_protocol_tq_msg_send(struct iosm_protocol *ipc_protocol,
0013 enum ipc_msg_prep_type msg_type,
0014 union ipc_msg_prep_args *prep_args,
0015 struct ipc_rsp *response)
0016 {
0017 int index = ipc_protocol_msg_prep(ipc_protocol->imem, msg_type,
0018 prep_args);
0019
0020
0021
0022
0023 if (index >= 0 && index < IPC_MEM_MSG_ENTRIES) {
0024 ipc_protocol->rsp_ring[index] = response;
0025 ipc_protocol_msg_hp_update(ipc_protocol->imem);
0026 }
0027
0028 return index;
0029 }
0030
0031
0032 static int ipc_protocol_tq_msg_send_cb(struct iosm_imem *ipc_imem, int arg,
0033 void *msg, size_t size)
0034 {
0035 struct ipc_call_msg_send_args *send_args = msg;
0036 struct iosm_protocol *ipc_protocol = ipc_imem->ipc_protocol;
0037
0038 return ipc_protocol_tq_msg_send(ipc_protocol, send_args->msg_type,
0039 send_args->prep_args,
0040 send_args->response);
0041 }
0042
0043
0044
0045
0046 static int ipc_protocol_tq_msg_remove(struct iosm_imem *ipc_imem, int arg,
0047 void *msg, size_t size)
0048 {
0049 struct iosm_protocol *ipc_protocol = ipc_imem->ipc_protocol;
0050
0051 ipc_protocol->rsp_ring[arg] = NULL;
0052 return 0;
0053 }
0054
0055 int ipc_protocol_msg_send(struct iosm_protocol *ipc_protocol,
0056 enum ipc_msg_prep_type prep,
0057 union ipc_msg_prep_args *prep_args)
0058 {
0059 struct ipc_call_msg_send_args send_args;
0060 unsigned int exec_timeout;
0061 struct ipc_rsp response;
0062 int index;
0063
0064 exec_timeout = (ipc_protocol_get_ap_exec_stage(ipc_protocol) ==
0065 IPC_MEM_EXEC_STAGE_RUN ?
0066 IPC_MSG_COMPLETE_RUN_DEFAULT_TIMEOUT :
0067 IPC_MSG_COMPLETE_BOOT_DEFAULT_TIMEOUT);
0068
0069
0070 might_sleep();
0071
0072 response.status = IPC_MEM_MSG_CS_INVALID;
0073 init_completion(&response.completion);
0074
0075 send_args.msg_type = prep;
0076 send_args.prep_args = prep_args;
0077 send_args.response = &response;
0078
0079
0080
0081
0082
0083 index = ipc_task_queue_send_task(ipc_protocol->imem,
0084 ipc_protocol_tq_msg_send_cb, 0,
0085 &send_args, 0, true);
0086
0087 if (index < 0) {
0088 dev_err(ipc_protocol->dev, "msg %d failed", prep);
0089 return index;
0090 }
0091
0092
0093 switch (wait_for_completion_timeout(&response.completion,
0094 msecs_to_jiffies(exec_timeout))) {
0095 case 0:
0096
0097
0098
0099
0100 ipc_task_queue_send_task(ipc_protocol->imem,
0101 ipc_protocol_tq_msg_remove, index,
0102 NULL, 0, true);
0103 dev_err(ipc_protocol->dev, "msg timeout");
0104 ipc_uevent_send(ipc_protocol->pcie->dev, UEVENT_MDM_TIMEOUT);
0105 break;
0106 default:
0107
0108 if (response.status != IPC_MEM_MSG_CS_SUCCESS) {
0109 dev_err(ipc_protocol->dev,
0110 "msg completion status error %d",
0111 response.status);
0112 return -EIO;
0113 }
0114 }
0115
0116 return 0;
0117 }
0118
0119 static int ipc_protocol_msg_send_host_sleep(struct iosm_protocol *ipc_protocol,
0120 u32 state)
0121 {
0122 union ipc_msg_prep_args prep_args = {
0123 .sleep.target = 0,
0124 .sleep.state = state,
0125 };
0126
0127 return ipc_protocol_msg_send(ipc_protocol, IPC_MSG_PREP_SLEEP,
0128 &prep_args);
0129 }
0130
0131 void ipc_protocol_doorbell_trigger(struct iosm_protocol *ipc_protocol,
0132 u32 identifier)
0133 {
0134 ipc_pm_signal_hpda_doorbell(&ipc_protocol->pm, identifier, true);
0135 }
0136
0137 bool ipc_protocol_pm_dev_sleep_handle(struct iosm_protocol *ipc_protocol)
0138 {
0139 u32 ipc_status = ipc_protocol_get_ipc_status(ipc_protocol);
0140 u32 requested;
0141
0142 if (ipc_status != IPC_MEM_DEVICE_IPC_RUNNING) {
0143 dev_err(ipc_protocol->dev,
0144 "irq ignored, CP IPC state is %d, should be RUNNING",
0145 ipc_status);
0146
0147
0148 return false;
0149 }
0150
0151
0152
0153
0154 requested = ipc_protocol_pm_dev_get_sleep_notification(ipc_protocol);
0155
0156 return ipc_pm_dev_slp_notification(&ipc_protocol->pm, requested);
0157 }
0158
0159 static int ipc_protocol_tq_wakeup_dev_slp(struct iosm_imem *ipc_imem, int arg,
0160 void *msg, size_t size)
0161 {
0162 struct iosm_pm *ipc_pm = &ipc_imem->ipc_protocol->pm;
0163
0164
0165 ipc_pm_trigger(ipc_pm, IPC_PM_UNIT_HS, true);
0166
0167 ipc_pm_trigger(ipc_pm, IPC_PM_UNIT_HS, false);
0168
0169 return 0;
0170 }
0171
0172 void ipc_protocol_s2idle_sleep(struct iosm_protocol *ipc_protocol, bool sleep)
0173 {
0174 ipc_pm_set_s2idle_sleep(&ipc_protocol->pm, sleep);
0175 }
0176
0177 bool ipc_protocol_suspend(struct iosm_protocol *ipc_protocol)
0178 {
0179 if (!ipc_pm_prepare_host_sleep(&ipc_protocol->pm))
0180 goto err;
0181
0182 ipc_task_queue_send_task(ipc_protocol->imem,
0183 ipc_protocol_tq_wakeup_dev_slp, 0, NULL, 0,
0184 true);
0185
0186 if (!ipc_pm_wait_for_device_active(&ipc_protocol->pm)) {
0187 ipc_uevent_send(ipc_protocol->pcie->dev, UEVENT_MDM_TIMEOUT);
0188 goto err;
0189 }
0190
0191
0192 dev_dbg(ipc_protocol->dev, "send TARGET_HOST, ENTER_SLEEP");
0193 if (ipc_protocol_msg_send_host_sleep(ipc_protocol,
0194 IPC_HOST_SLEEP_ENTER_SLEEP)) {
0195
0196 ipc_protocol->pm.host_pm_state = IPC_MEM_HOST_PM_ACTIVE;
0197 goto err;
0198 }
0199
0200 ipc_protocol->pm.host_pm_state = IPC_MEM_HOST_PM_SLEEP;
0201 return true;
0202 err:
0203 return false;
0204 }
0205
0206 bool ipc_protocol_resume(struct iosm_protocol *ipc_protocol)
0207 {
0208 if (!ipc_pm_prepare_host_active(&ipc_protocol->pm))
0209 return false;
0210
0211 dev_dbg(ipc_protocol->dev, "send TARGET_HOST, EXIT_SLEEP");
0212 if (ipc_protocol_msg_send_host_sleep(ipc_protocol,
0213 IPC_HOST_SLEEP_EXIT_SLEEP)) {
0214 ipc_protocol->pm.host_pm_state = IPC_MEM_HOST_PM_SLEEP;
0215 return false;
0216 }
0217
0218 ipc_protocol->pm.host_pm_state = IPC_MEM_HOST_PM_ACTIVE;
0219
0220 return true;
0221 }
0222
0223 struct iosm_protocol *ipc_protocol_init(struct iosm_imem *ipc_imem)
0224 {
0225 struct iosm_protocol *ipc_protocol =
0226 kzalloc(sizeof(*ipc_protocol), GFP_KERNEL);
0227 struct ipc_protocol_context_info *p_ci;
0228 u64 addr;
0229
0230 if (!ipc_protocol)
0231 return NULL;
0232
0233 ipc_protocol->dev = ipc_imem->dev;
0234 ipc_protocol->pcie = ipc_imem->pcie;
0235 ipc_protocol->imem = ipc_imem;
0236 ipc_protocol->p_ap_shm = NULL;
0237 ipc_protocol->phy_ap_shm = 0;
0238
0239 ipc_protocol->old_msg_tail = 0;
0240
0241 ipc_protocol->p_ap_shm =
0242 dma_alloc_coherent(&ipc_protocol->pcie->pci->dev,
0243 sizeof(*ipc_protocol->p_ap_shm),
0244 &ipc_protocol->phy_ap_shm, GFP_KERNEL);
0245
0246 if (!ipc_protocol->p_ap_shm) {
0247 dev_err(ipc_protocol->dev, "pci shm alloc error");
0248 kfree(ipc_protocol);
0249 return NULL;
0250 }
0251
0252
0253 addr = ipc_protocol->phy_ap_shm;
0254 p_ci = &ipc_protocol->p_ap_shm->ci;
0255 p_ci->device_info_addr =
0256 addr + offsetof(struct ipc_protocol_ap_shm, device_info);
0257 p_ci->head_array =
0258 addr + offsetof(struct ipc_protocol_ap_shm, head_array);
0259 p_ci->tail_array =
0260 addr + offsetof(struct ipc_protocol_ap_shm, tail_array);
0261 p_ci->msg_head = addr + offsetof(struct ipc_protocol_ap_shm, msg_head);
0262 p_ci->msg_tail = addr + offsetof(struct ipc_protocol_ap_shm, msg_tail);
0263 p_ci->msg_ring_addr =
0264 addr + offsetof(struct ipc_protocol_ap_shm, msg_ring);
0265 p_ci->msg_ring_entries = cpu_to_le16(IPC_MEM_MSG_ENTRIES);
0266 p_ci->msg_irq_vector = IPC_MSG_IRQ_VECTOR;
0267 p_ci->device_info_irq_vector = IPC_DEVICE_IRQ_VECTOR;
0268
0269 ipc_mmio_set_contex_info_addr(ipc_imem->mmio, addr);
0270
0271 ipc_pm_init(ipc_protocol);
0272
0273 return ipc_protocol;
0274 }
0275
0276 void ipc_protocol_deinit(struct iosm_protocol *proto)
0277 {
0278 dma_free_coherent(&proto->pcie->pci->dev, sizeof(*proto->p_ap_shm),
0279 proto->p_ap_shm, proto->phy_ap_shm);
0280
0281 ipc_pm_deinit(proto);
0282 kfree(proto);
0283 }