1ff2743e5SAnson Huang /* 2ff2743e5SAnson Huang * Copyright (c) 2015-2018, ARM Limited and Contributors. All rights reserved. 3ff2743e5SAnson Huang * 4ff2743e5SAnson Huang * SPDX-License-Identifier: BSD-3-Clause 5ff2743e5SAnson Huang */ 6ff2743e5SAnson Huang 7*09d40e0eSAntonio Nino Diaz #include <stdlib.h> 8*09d40e0eSAntonio Nino Diaz 9*09d40e0eSAntonio Nino Diaz #include <lib/bakery_lock.h> 10*09d40e0eSAntonio Nino Diaz 11ff2743e5SAnson Huang #include <sci/sci_scfw.h> 12ff2743e5SAnson Huang #include <sci/sci_ipc.h> 13ff2743e5SAnson Huang #include <sci/sci_rpc.h> 14ff2743e5SAnson Huang #include "imx8_mu.h" 15ff2743e5SAnson Huang 16ff2743e5SAnson Huang DEFINE_BAKERY_LOCK(sc_ipc_bakery_lock); 17ff2743e5SAnson Huang #define sc_ipc_lock_init() bakery_lock_init(&sc_ipc_bakery_lock) 18ff2743e5SAnson Huang #define sc_ipc_lock() bakery_lock_get(&sc_ipc_bakery_lock) 19ff2743e5SAnson Huang #define sc_ipc_unlock() bakery_lock_release(&sc_ipc_bakery_lock) 20ff2743e5SAnson Huang 21ff2743e5SAnson Huang void sc_call_rpc(sc_ipc_t ipc, sc_rpc_msg_t *msg, bool no_resp) 22ff2743e5SAnson Huang { 23ff2743e5SAnson Huang sc_ipc_lock(); 24ff2743e5SAnson Huang 25ff2743e5SAnson Huang sc_ipc_write(ipc, msg); 26ff2743e5SAnson Huang if (!no_resp) 27ff2743e5SAnson Huang sc_ipc_read(ipc, msg); 28ff2743e5SAnson Huang 29ff2743e5SAnson Huang sc_ipc_unlock(); 30ff2743e5SAnson Huang } 31ff2743e5SAnson Huang 32ff2743e5SAnson Huang sc_err_t sc_ipc_open(sc_ipc_t *ipc, sc_ipc_id_t id) 33ff2743e5SAnson Huang { 34ff2743e5SAnson Huang uint32_t base = id; 35ff2743e5SAnson Huang uint32_t i; 36ff2743e5SAnson Huang 37ff2743e5SAnson Huang /* Get MU base associated with IPC channel */ 38ff2743e5SAnson Huang if ((ipc == NULL) || (base == 0)) 39ff2743e5SAnson Huang return SC_ERR_IPC; 40ff2743e5SAnson Huang 41ff2743e5SAnson Huang sc_ipc_lock_init(); 42ff2743e5SAnson Huang 43ff2743e5SAnson Huang /* Init MU */ 44ff2743e5SAnson Huang MU_Init(base); 45ff2743e5SAnson Huang 46ff2743e5SAnson Huang /* Enable all RX interrupts */ 47ff2743e5SAnson Huang for (i = 0; i < MU_RR_COUNT; i++) { 48ff2743e5SAnson Huang MU_EnableRxFullInt(base, i); 49ff2743e5SAnson Huang } 50ff2743e5SAnson Huang 51ff2743e5SAnson Huang /* Return MU address as handle */ 52ff2743e5SAnson Huang *ipc = (sc_ipc_t) id; 53ff2743e5SAnson Huang 54ff2743e5SAnson Huang return SC_ERR_NONE; 55ff2743e5SAnson Huang } 56ff2743e5SAnson Huang 57ff2743e5SAnson Huang void sc_ipc_close(sc_ipc_t ipc) 58ff2743e5SAnson Huang { 59ff2743e5SAnson Huang uint32_t base = ipc; 60ff2743e5SAnson Huang 61ff2743e5SAnson Huang if (base != 0) 62ff2743e5SAnson Huang MU_Init(base); 63ff2743e5SAnson Huang } 64ff2743e5SAnson Huang 65ff2743e5SAnson Huang void sc_ipc_read(sc_ipc_t ipc, void *data) 66ff2743e5SAnson Huang { 67ff2743e5SAnson Huang uint32_t base = ipc; 68ff2743e5SAnson Huang sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data; 69ff2743e5SAnson Huang uint8_t count = 0; 70ff2743e5SAnson Huang 71ff2743e5SAnson Huang /* Check parms */ 72ff2743e5SAnson Huang if ((base == 0) || (msg == NULL)) 73ff2743e5SAnson Huang return; 74ff2743e5SAnson Huang 75ff2743e5SAnson Huang /* Read first word */ 76ff2743e5SAnson Huang MU_ReceiveMsg(base, 0, (uint32_t *) msg); 77ff2743e5SAnson Huang count++; 78ff2743e5SAnson Huang 79ff2743e5SAnson Huang /* Check size */ 80ff2743e5SAnson Huang if (msg->size > SC_RPC_MAX_MSG) { 81ff2743e5SAnson Huang *((uint32_t *) msg) = 0; 82ff2743e5SAnson Huang return; 83ff2743e5SAnson Huang } 84ff2743e5SAnson Huang 85ff2743e5SAnson Huang /* Read remaining words */ 86ff2743e5SAnson Huang while (count < msg->size) { 87ff2743e5SAnson Huang MU_ReceiveMsg(base, count % MU_RR_COUNT, 88ff2743e5SAnson Huang &(msg->DATA.u32[count - 1])); 89ff2743e5SAnson Huang count++; 90ff2743e5SAnson Huang } 91ff2743e5SAnson Huang } 92ff2743e5SAnson Huang 93ff2743e5SAnson Huang void sc_ipc_write(sc_ipc_t ipc, void *data) 94ff2743e5SAnson Huang { 95ff2743e5SAnson Huang sc_rpc_msg_t *msg = (sc_rpc_msg_t *) data; 96ff2743e5SAnson Huang uint32_t base = ipc; 97ff2743e5SAnson Huang uint8_t count = 0; 98ff2743e5SAnson Huang 99ff2743e5SAnson Huang /* Check parms */ 100ff2743e5SAnson Huang if ((base == 0) || (msg == NULL)) 101ff2743e5SAnson Huang return; 102ff2743e5SAnson Huang 103ff2743e5SAnson Huang /* Check size */ 104ff2743e5SAnson Huang if (msg->size > SC_RPC_MAX_MSG) 105ff2743e5SAnson Huang return; 106ff2743e5SAnson Huang 107ff2743e5SAnson Huang /* Write first word */ 108ff2743e5SAnson Huang MU_SendMessage(base, 0, *((uint32_t *) msg)); 109ff2743e5SAnson Huang count++; 110ff2743e5SAnson Huang 111ff2743e5SAnson Huang /* Write remaining words */ 112ff2743e5SAnson Huang while (count < msg->size) { 113ff2743e5SAnson Huang MU_SendMessage(base, count % MU_TR_COUNT, 114ff2743e5SAnson Huang msg->DATA.u32[count - 1]); 115ff2743e5SAnson Huang count++; 116ff2743e5SAnson Huang } 117ff2743e5SAnson Huang } 118ff2743e5SAnson Huang 119