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