blob: 8f8c39c95cfe341f5269b8f2e994674fa99d1e6e [file] [log] [blame]
/* Copyright Statement:
*
* This software/firmware and related documentation ("MediaTek Software") are
* protected under relevant copyright laws. The information contained herein
* is confidential and proprietary to MediaTek Inc. and/or its licensors.
* Without the prior written permission of MediaTek inc. and/or its licensors,
* any reproduction, modification, use or disclosure of MediaTek Software,
* and information contained herein, in whole or in part, shall be strictly
* prohibited.
*/
/* MediaTek Inc. (C) 2019. All rights reserved.
*
* BY OPENING THIS FILE, RECEIVER HEREBY UNEQUIVOCALLY ACKNOWLEDGES AND AGREES
* THAT THE SOFTWARE/FIRMWARE AND ITS DOCUMENTATIONS ("MEDIATEK SOFTWARE")
* RECEIVED FROM MEDIATEK AND/OR ITS REPRESENTATIVES ARE PROVIDED TO RECEIVER ON
* AN "AS-IS" BASIS ONLY. MEDIATEK EXPRESSLY DISCLAIMS ANY AND ALL WARRANTIES,
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE OR NONINFRINGEMENT.
* NEITHER DOES MEDIATEK PROVIDE ANY WARRANTY WHATSOEVER WITH RESPECT TO THE
* SOFTWARE OF ANY THIRD PARTY WHICH MAY BE USED BY, INCORPORATED IN, OR
* SUPPLIED WITH THE MEDIATEK SOFTWARE, AND RECEIVER AGREES TO LOOK ONLY TO SUCH
* THIRD PARTY FOR ANY WARRANTY CLAIM RELATING THERETO. RECEIVER EXPRESSLY
* ACKNOWLEDGES THAT IT IS RECEIVER\'S SOLE RESPONSIBILITY TO OBTAIN FROM ANY
* THIRD PARTY ALL PROPER LICENSES CONTAINED IN MEDIATEK SOFTWARE. MEDIATEK
* SHALL ALSO NOT BE RESPONSIBLE FOR ANY MEDIATEK SOFTWARE RELEASES MADE TO
* RECEIVER\'S SPECIFICATION OR TO CONFORM TO A PARTICULAR STANDARD OR OPEN
* FORUM. RECEIVER\'S SOLE AND EXCLUSIVE REMEDY AND MEDIATEK\'S ENTIRE AND
* CUMULATIVE LIABILITY WITH RESPECT TO THE MEDIATEK SOFTWARE RELEASED HEREUNDER
* WILL BE, AT MEDIATEK\'S OPTION, TO REVISE OR REPLACE THE MEDIATEK SOFTWARE
* AT ISSUE, OR REFUND ANY SOFTWARE LICENSE FEES OR SERVICE CHARGE PAID BY
* RECEIVER TO MEDIATEK FOR SUCH MEDIATEK SOFTWARE AT ISSUE.
*
* The following software/firmware and/or related documentation
* ("MediaTek Software") have been modified by MediaTek Inc. All revisions are
* subject to any receiver\'s applicable license agreements with MediaTek Inc.
*/
#include "scp_ipi.h"
#include "encoding.h"
static struct ipi_wrapper ipi_legacy_id [] = IPI_LEGACY_GROUP;
ipi_handler_t mpool_handle_list[IPI_WRAPPER_TOTAL - IPI_MPOOL - 1];
struct ipi_legacy_pkt {
unsigned int id;
unsigned int len;
void *data;
};
/*
* This is a handler for handling legacy ipi callback function
*/
static void legacy_handler(int id, void *prdata, void *data, unsigned int len)
{
ipi_handler_t handler;
unsigned int ptr = (unsigned int)data;
struct ipi_legacy_pkt pkt;
/* variation length will only support chre, chrex and sensor for reducing
* slot and cpu time cost by memcpy.
*/
pkt.id = *(unsigned int *)ptr;
pkt.len = *(unsigned int *)(ptr + 4);
pkt.data = (void *)(ptr + 8);
if (pkt.id > IPI_MPOOL)
handler = mpool_handle_list[pkt.id - IPI_MPOOL - 1];
else
handler = (ipi_handler_t)prdata;
handler(pkt.id, pkt.data, pkt.len);
}
/*
* Wrapper api for legacy api and supports only legacy features
* which is listed in ipi_legacy_id[]
*/
ipi_status scp_ipi_send(enum ipi_id id, void* buf, uint32_t len, uint32_t wait,
enum ipi_dir dir)
{
int ret = 0, tmp_id;
void *ptr;
if (id >= IPI_WRAPPER_TOTAL || id == IPI_MPOOL) {
PRINTF_E("%s: id not support\n", __func__);
return ERROR;
}
if (id > IPI_MPOOL)
tmp_id = IPI_MPOOL;
else
tmp_id = id;
if (len > (ipi_legacy_id[tmp_id].out_size - 2) * MBOX_SLOT_SIZE) {
PRINTF_E("%s: len overflow\n", __func__);
return ERROR;
}
/* variation length will only support chre and sensor for reducing slot
* and cpu time cost by memcpy.
*/
char pkt[ipi_legacy_id[tmp_id].out_size * MBOX_SLOT_SIZE];
memcpy((void *)pkt, (void *)&id, sizeof(uint32_t));
memcpy((void *)(pkt + 4), (void *)&len, sizeof(uint32_t));
memcpy((void *)(pkt + 8), buf, len);
ptr = pkt;
if (mrv_read_csr(CSR_MHARTID) == 0)
ret = ipi_send(ipi_legacy_id[tmp_id].out_id_0, ptr,
(int)ipi_legacy_id[tmp_id].out_size,
wait * IPI_WAIT_LEGACY);
else
ret = ipi_send(ipi_legacy_id[tmp_id].out_id_1, ptr,
(int)ipi_legacy_id[tmp_id].out_size,
wait * IPI_WAIT_LEGACY);
if (ret == IPI_ACTION_DONE)
return DONE;
else if (ret == IPI_PIN_BUSY)
return BUSY;
else
return ERROR;
}
ipi_status scp_ipi_registration(enum ipi_id id, ipi_handler_t handler,
const char *name)
{
int ret = 0;
if (id >= IPI_WRAPPER_TOTAL || id == IPI_MPOOL) {
PRINTF_E("%s: id not support\n", __func__);
return ERROR;
}
if (id > IPI_MPOOL) {
/* if there's any new ipi, hook handler only */
mpool_handle_list[id - IPI_MPOOL - 1] = handler;
return DONE;
}
if (mrv_read_csr(CSR_MHARTID) == 0) {
ret = ipi_register(ipi_legacy_id[id].in_id_0, legacy_handler,
handler, ipi_legacy_id[id].msg);
} else {
ret = ipi_register(ipi_legacy_id[id].in_id_1, legacy_handler,
handler, ipi_legacy_id[id].msg);
}
if (ret == IPI_ACTION_DONE)
return DONE;
else
return ERROR;
}
void scp_legacy_ipi_init(void)
{
int ret = 0;
if (mrv_read_csr(CSR_MHARTID) == 0) {
ret = ipi_register(IPI_IN_SCP_MPOOL_0, legacy_handler, 0,
msg_legacy_ipi_mpool);
} else {
ret = ipi_register(IPI_IN_SCP_MPOOL_1, legacy_handler, 0,
msg_legacy_ipi_mpool);
}
if (ret)
PRINTF_E("ipi mpool register fail, ret %d\n", ret);
}