| xj | b04a402 | 2021-11-25 15:01:52 +0800 | [diff] [blame^] | 1 | /* Copyright Statement: |
| 2 | * |
| 3 | * This software/firmware and related documentation ("MediaTek Software") are |
| 4 | * protected under relevant copyright laws. The information contained herein |
| 5 | * is confidential and proprietary to MediaTek Inc. and/or its licensors. |
| 6 | * Without the prior written permission of MediaTek inc. and/or its licensors, |
| 7 | * any reproduction, modification, use or disclosure of MediaTek Software, |
| 8 | * and information contained herein, in whole or in part, shall be strictly |
| 9 | * prohibited. |
| 10 | */ |
| 11 | /* MediaTek Inc. (C) 2019. All rights reserved. |
| 12 | * |
| 13 | * BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES |
| 14 | * THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE") |
| 15 | * RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON |
| 16 | * AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES, |
| 17 | * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF |
| 18 | * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT. |
| 19 | * NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE |
| 20 | * SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR |
| 21 | * SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH |
| 22 | * THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY |
| 23 | * ACKNOWLEDGES THAT IT IS RECEIVER\'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY |
| 24 | * THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK |
| 25 | * SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO |
| 26 | * RECEIVER\'S SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN |
| 27 | * FORUM. RECEIVER\'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK\'S ENTIRE AND |
| 28 | * CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER |
| 29 | * WILL BE, AT MEDIATEK\'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE |
| 30 | * AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY |
| 31 | * RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE. |
| 32 | * |
| 33 | * The following software/firmware and/or related documentation |
| 34 | * ("MediaTek Software") have been modified by MediaTek Inc. All revisions are |
| 35 | * subject to any receiver\'s applicable license agreements with MediaTek Inc. |
| 36 | */ |
| 37 | |
| 38 | #include "scp_ipi.h" |
| 39 | #include "encoding.h" |
| 40 | |
| 41 | |
| 42 | static struct ipi_wrapper ipi_legacy_id [] = IPI_LEGACY_GROUP; |
| 43 | ipi_handler_t mpool_handle_list[IPI_WRAPPER_TOTAL - IPI_MPOOL - 1]; |
| 44 | struct ipi_legacy_pkt { |
| 45 | unsigned int id; |
| 46 | unsigned int len; |
| 47 | void *data; |
| 48 | }; |
| 49 | |
| 50 | /* |
| 51 | * This is a handler for handling legacy ipi callback function |
| 52 | */ |
| 53 | static void legacy_handler(int id, void *prdata, void *data, unsigned int len) |
| 54 | { |
| 55 | ipi_handler_t handler; |
| 56 | unsigned int ptr = (unsigned int)data; |
| 57 | struct ipi_legacy_pkt pkt; |
| 58 | |
| 59 | /* variation length will only support chre, chrex and sensor for reducing |
| 60 | * slot and cpu time cost by memcpy. |
| 61 | */ |
| 62 | pkt.id = *(unsigned int *)ptr; |
| 63 | pkt.len = *(unsigned int *)(ptr + 4); |
| 64 | pkt.data = (void *)(ptr + 8); |
| 65 | |
| 66 | if (pkt.id > IPI_MPOOL) |
| 67 | handler = mpool_handle_list[pkt.id - IPI_MPOOL - 1]; |
| 68 | else |
| 69 | handler = (ipi_handler_t)prdata; |
| 70 | handler(pkt.id, pkt.data, pkt.len); |
| 71 | } |
| 72 | |
| 73 | /* |
| 74 | * Wrapper api for legacy api and supports only legacy features |
| 75 | * which is listed in ipi_legacy_id[] |
| 76 | */ |
| 77 | ipi_status scp_ipi_send(enum ipi_id id, void* buf, uint32_t len, uint32_t wait, |
| 78 | enum ipi_dir dir) |
| 79 | { |
| 80 | int ret = 0, tmp_id; |
| 81 | void *ptr; |
| 82 | |
| 83 | if (id >= IPI_WRAPPER_TOTAL || id == IPI_MPOOL) { |
| 84 | PRINTF_E("%s: id not support\n", __func__); |
| 85 | return ERROR; |
| 86 | } |
| 87 | |
| 88 | if (id > IPI_MPOOL) |
| 89 | tmp_id = IPI_MPOOL; |
| 90 | else |
| 91 | tmp_id = id; |
| 92 | |
| 93 | if (len > (ipi_legacy_id[tmp_id].out_size - 2) * MBOX_SLOT_SIZE) { |
| 94 | PRINTF_E("%s: len overflow\n", __func__); |
| 95 | return ERROR; |
| 96 | } |
| 97 | |
| 98 | /* variation length will only support chre and sensor for reducing slot |
| 99 | * and cpu time cost by memcpy. |
| 100 | */ |
| 101 | char pkt[ipi_legacy_id[tmp_id].out_size * MBOX_SLOT_SIZE]; |
| 102 | memcpy((void *)pkt, (void *)&id, sizeof(uint32_t)); |
| 103 | memcpy((void *)(pkt + 4), (void *)&len, sizeof(uint32_t)); |
| 104 | memcpy((void *)(pkt + 8), buf, len); |
| 105 | ptr = pkt; |
| 106 | |
| 107 | if (mrv_read_csr(CSR_MHARTID) == 0) |
| 108 | ret = ipi_send(ipi_legacy_id[tmp_id].out_id_0, ptr, |
| 109 | (int)ipi_legacy_id[tmp_id].out_size, |
| 110 | wait * IPI_WAIT_LEGACY); |
| 111 | else |
| 112 | ret = ipi_send(ipi_legacy_id[tmp_id].out_id_1, ptr, |
| 113 | (int)ipi_legacy_id[tmp_id].out_size, |
| 114 | wait * IPI_WAIT_LEGACY); |
| 115 | |
| 116 | if (ret == IPI_ACTION_DONE) |
| 117 | return DONE; |
| 118 | else if (ret == IPI_PIN_BUSY) |
| 119 | return BUSY; |
| 120 | else |
| 121 | return ERROR; |
| 122 | } |
| 123 | |
| 124 | ipi_status scp_ipi_registration(enum ipi_id id, ipi_handler_t handler, |
| 125 | const char *name) |
| 126 | { |
| 127 | int ret = 0; |
| 128 | |
| 129 | if (id >= IPI_WRAPPER_TOTAL || id == IPI_MPOOL) { |
| 130 | PRINTF_E("%s: id not support\n", __func__); |
| 131 | return ERROR; |
| 132 | } |
| 133 | |
| 134 | if (id > IPI_MPOOL) { |
| 135 | /* if there's any new ipi, hook handler only */ |
| 136 | mpool_handle_list[id - IPI_MPOOL - 1] = handler; |
| 137 | return DONE; |
| 138 | } |
| 139 | |
| 140 | if (mrv_read_csr(CSR_MHARTID) == 0) { |
| 141 | ret = ipi_register(ipi_legacy_id[id].in_id_0, legacy_handler, |
| 142 | handler, ipi_legacy_id[id].msg); |
| 143 | } else { |
| 144 | ret = ipi_register(ipi_legacy_id[id].in_id_1, legacy_handler, |
| 145 | handler, ipi_legacy_id[id].msg); |
| 146 | } |
| 147 | |
| 148 | if (ret == IPI_ACTION_DONE) |
| 149 | return DONE; |
| 150 | else |
| 151 | return ERROR; |
| 152 | } |
| 153 | |
| 154 | void scp_legacy_ipi_init(void) |
| 155 | { |
| 156 | int ret = 0; |
| 157 | |
| 158 | if (mrv_read_csr(CSR_MHARTID) == 0) { |
| 159 | ret = ipi_register(IPI_IN_SCP_MPOOL_0, legacy_handler, 0, |
| 160 | msg_legacy_ipi_mpool); |
| 161 | } else { |
| 162 | ret = ipi_register(IPI_IN_SCP_MPOOL_1, legacy_handler, 0, |
| 163 | msg_legacy_ipi_mpool); |
| 164 | } |
| 165 | |
| 166 | if (ret) |
| 167 | PRINTF_E("ipi mpool register fail, ret %d\n", ret); |
| 168 | } |