1*50cabf6dSSamuel Holland /* 2*50cabf6dSSamuel Holland * Copyright (c) 2017-2019, ARM Limited and Contributors. All rights reserved. 3*50cabf6dSSamuel Holland * 4*50cabf6dSSamuel Holland * SPDX-License-Identifier: BSD-3-Clause 5*50cabf6dSSamuel Holland */ 6*50cabf6dSSamuel Holland 7*50cabf6dSSamuel Holland #include <assert.h> 8*50cabf6dSSamuel Holland #include <stdbool.h> 9*50cabf6dSSamuel Holland 10*50cabf6dSSamuel Holland #include <drivers/delay_timer.h> 11*50cabf6dSSamuel Holland #include <lib/bakery_lock.h> 12*50cabf6dSSamuel Holland #include <lib/mmio.h> 13*50cabf6dSSamuel Holland #include <lib/utils_def.h> 14*50cabf6dSSamuel Holland 15*50cabf6dSSamuel Holland #include <sunxi_mmap.h> 16*50cabf6dSSamuel Holland 17*50cabf6dSSamuel Holland #define REMOTE_IRQ_EN_REG 0x0040 18*50cabf6dSSamuel Holland #define REMOTE_IRQ_STAT_REG 0x0050 19*50cabf6dSSamuel Holland #define LOCAL_IRQ_EN_REG 0x0060 20*50cabf6dSSamuel Holland #define LOCAL_IRQ_STAT_REG 0x0070 21*50cabf6dSSamuel Holland 22*50cabf6dSSamuel Holland #define RX_IRQ(n) BIT(0 + 2 * (n)) 23*50cabf6dSSamuel Holland #define TX_IRQ(n) BIT(1 + 2 * (n)) 24*50cabf6dSSamuel Holland 25*50cabf6dSSamuel Holland #define FIFO_STAT_REG(n) (0x0100 + 0x4 * (n)) 26*50cabf6dSSamuel Holland #define FIFO_STAT_MASK GENMASK(0, 0) 27*50cabf6dSSamuel Holland 28*50cabf6dSSamuel Holland #define MSG_STAT_REG(n) (0x0140 + 0x4 * (n)) 29*50cabf6dSSamuel Holland #define MSG_STAT_MASK GENMASK(2, 0) 30*50cabf6dSSamuel Holland 31*50cabf6dSSamuel Holland #define MSG_DATA_REG(n) (0x0180 + 0x4 * (n)) 32*50cabf6dSSamuel Holland 33*50cabf6dSSamuel Holland #define RX_CHAN 1 34*50cabf6dSSamuel Holland #define TX_CHAN 0 35*50cabf6dSSamuel Holland 36*50cabf6dSSamuel Holland #define MHU_MAX_SLOT_ID 31 37*50cabf6dSSamuel Holland 38*50cabf6dSSamuel Holland #define MHU_TIMEOUT_DELAY 10 39*50cabf6dSSamuel Holland #define MHU_TIMEOUT_ITERS 10000 40*50cabf6dSSamuel Holland 41*50cabf6dSSamuel Holland static DEFINE_BAKERY_LOCK(mhu_secure_message_lock); 42*50cabf6dSSamuel Holland sunxi_msgbox_last_tx_done(unsigned int chan)43*50cabf6dSSamuel Hollandstatic bool sunxi_msgbox_last_tx_done(unsigned int chan) 44*50cabf6dSSamuel Holland { 45*50cabf6dSSamuel Holland uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + REMOTE_IRQ_STAT_REG); 46*50cabf6dSSamuel Holland 47*50cabf6dSSamuel Holland return (stat & RX_IRQ(chan)) == 0U; 48*50cabf6dSSamuel Holland } 49*50cabf6dSSamuel Holland sunxi_msgbox_peek_data(unsigned int chan)50*50cabf6dSSamuel Hollandstatic bool sunxi_msgbox_peek_data(unsigned int chan) 51*50cabf6dSSamuel Holland { 52*50cabf6dSSamuel Holland uint32_t stat = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_STAT_REG(chan)); 53*50cabf6dSSamuel Holland 54*50cabf6dSSamuel Holland return (stat & MSG_STAT_MASK) != 0U; 55*50cabf6dSSamuel Holland } 56*50cabf6dSSamuel Holland mhu_secure_message_start(unsigned int slot_id __unused)57*50cabf6dSSamuel Hollandvoid mhu_secure_message_start(unsigned int slot_id __unused) 58*50cabf6dSSamuel Holland { 59*50cabf6dSSamuel Holland uint32_t timeout = MHU_TIMEOUT_ITERS; 60*50cabf6dSSamuel Holland 61*50cabf6dSSamuel Holland bakery_lock_get(&mhu_secure_message_lock); 62*50cabf6dSSamuel Holland 63*50cabf6dSSamuel Holland /* Wait for all previous messages to be acknowledged. */ 64*50cabf6dSSamuel Holland while (!sunxi_msgbox_last_tx_done(TX_CHAN) && --timeout) 65*50cabf6dSSamuel Holland udelay(MHU_TIMEOUT_DELAY); 66*50cabf6dSSamuel Holland } 67*50cabf6dSSamuel Holland mhu_secure_message_send(unsigned int slot_id)68*50cabf6dSSamuel Hollandvoid mhu_secure_message_send(unsigned int slot_id) 69*50cabf6dSSamuel Holland { 70*50cabf6dSSamuel Holland mmio_write_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(TX_CHAN), BIT(slot_id)); 71*50cabf6dSSamuel Holland } 72*50cabf6dSSamuel Holland mhu_secure_message_wait(void)73*50cabf6dSSamuel Hollanduint32_t mhu_secure_message_wait(void) 74*50cabf6dSSamuel Holland { 75*50cabf6dSSamuel Holland uint32_t timeout = MHU_TIMEOUT_ITERS; 76*50cabf6dSSamuel Holland uint32_t msg = 0; 77*50cabf6dSSamuel Holland 78*50cabf6dSSamuel Holland /* Wait for a message from the SCP. */ 79*50cabf6dSSamuel Holland while (!sunxi_msgbox_peek_data(RX_CHAN) && --timeout) 80*50cabf6dSSamuel Holland udelay(MHU_TIMEOUT_DELAY); 81*50cabf6dSSamuel Holland 82*50cabf6dSSamuel Holland /* Return the most recent message in the FIFO. */ 83*50cabf6dSSamuel Holland while (sunxi_msgbox_peek_data(RX_CHAN)) 84*50cabf6dSSamuel Holland msg = mmio_read_32(SUNXI_MSGBOX_BASE + MSG_DATA_REG(RX_CHAN)); 85*50cabf6dSSamuel Holland 86*50cabf6dSSamuel Holland return msg; 87*50cabf6dSSamuel Holland } 88*50cabf6dSSamuel Holland mhu_secure_message_end(unsigned int slot_id)89*50cabf6dSSamuel Hollandvoid mhu_secure_message_end(unsigned int slot_id) 90*50cabf6dSSamuel Holland { 91*50cabf6dSSamuel Holland /* Acknowledge a response by clearing the IRQ status. */ 92*50cabf6dSSamuel Holland mmio_write_32(SUNXI_MSGBOX_BASE + LOCAL_IRQ_STAT_REG, RX_IRQ(RX_CHAN)); 93*50cabf6dSSamuel Holland 94*50cabf6dSSamuel Holland bakery_lock_release(&mhu_secure_message_lock); 95*50cabf6dSSamuel Holland } 96