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