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