blob: 981df9c4327fabbfb77ded1ba1545c4b8674c9a2 [file] [log] [blame]
Dan Handley9df48042015-03-19 18:58:55 +00001/*
Samarth Parikh59cfa132017-11-23 14:23:21 +05302 * Copyright (c) 2014-2018, ARM Limited and Contributors. All rights reserved.
Dan Handley9df48042015-03-19 18:58:55 +00003 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Dan Handley9df48042015-03-19 18:58:55 +00005 */
6
Sandrine Bailleux04b66d82015-03-18 14:52:53 +00007#include <assert.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008
9#include <platform_def.h>
10
11#include <arch_helpers.h>
12#include <lib/bakery_lock.h>
13#include <lib/mmio.h>
14
Dan Handley9df48042015-03-19 18:58:55 +000015#include <plat_arm.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000016
Dan Handley9df48042015-03-19 18:58:55 +000017#include "css_mhu.h"
18
19/* SCP MHU secure channel registers */
20#define SCP_INTR_S_STAT 0x200
21#define SCP_INTR_S_SET 0x208
22#define SCP_INTR_S_CLEAR 0x210
23
24/* CPU MHU secure channel registers */
25#define CPU_INTR_S_STAT 0x300
26#define CPU_INTR_S_SET 0x308
27#define CPU_INTR_S_CLEAR 0x310
28
Jeenu Viswambharan749d25b2017-08-23 14:12:59 +010029ARM_INSTANTIATE_LOCK;
Dan Handley9df48042015-03-19 18:58:55 +000030
31/* Weak definition may be overridden in specific CSS based platform */
32#pragma weak plat_arm_pwrc_setup
33
34
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000035/*
36 * Slot 31 is reserved because the MHU hardware uses this register bit to
37 * indicate a non-secure access attempt. The total number of available slots is
38 * therefore 31 [30:0].
39 */
40#define MHU_MAX_SLOT_ID 30
41
42void mhu_secure_message_start(unsigned int slot_id)
Dan Handley9df48042015-03-19 18:58:55 +000043{
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000044 assert(slot_id <= MHU_MAX_SLOT_ID);
45
Dan Handley9df48042015-03-19 18:58:55 +000046 arm_lock_get();
47
48 /* Make sure any previous command has finished */
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000049 while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) &
50 (1 << slot_id))
Dan Handley9df48042015-03-19 18:58:55 +000051 ;
52}
53
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000054void mhu_secure_message_send(unsigned int slot_id)
Dan Handley9df48042015-03-19 18:58:55 +000055{
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000056 assert(slot_id <= MHU_MAX_SLOT_ID);
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000057 assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) &
58 (1 << slot_id)));
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000059
60 /* Send command to SCP */
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000061 mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id);
Dan Handley9df48042015-03-19 18:58:55 +000062}
63
64uint32_t mhu_secure_message_wait(void)
65{
66 /* Wait for response from SCP */
67 uint32_t response;
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000068 while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT)))
Dan Handley9df48042015-03-19 18:58:55 +000069 ;
70
71 return response;
72}
73
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000074void mhu_secure_message_end(unsigned int slot_id)
Dan Handley9df48042015-03-19 18:58:55 +000075{
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000076 assert(slot_id <= MHU_MAX_SLOT_ID);
77
Dan Handley9df48042015-03-19 18:58:55 +000078 /*
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000079 * Clear any response we got by writing one in the relevant slot bit to
80 * the CLEAR register
Dan Handley9df48042015-03-19 18:58:55 +000081 */
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000082 mmio_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id);
Dan Handley9df48042015-03-19 18:58:55 +000083
84 arm_lock_release();
85}
86
Daniel Boulbyf45a4bb2018-09-18 13:26:03 +010087void __init mhu_secure_init(void)
Dan Handley9df48042015-03-19 18:58:55 +000088{
89 arm_lock_init();
90
91 /*
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000092 * The STAT register resets to zero. Ensure it is in the expected state,
93 * as a stale or garbage value would make us think it's a message we've
94 * already sent.
Dan Handley9df48042015-03-19 18:58:55 +000095 */
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000096 assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0);
Dan Handley9df48042015-03-19 18:58:55 +000097}
98
Daniel Boulbyf45a4bb2018-09-18 13:26:03 +010099void __init plat_arm_pwrc_setup(void)
Dan Handley9df48042015-03-19 18:58:55 +0000100{
101 mhu_secure_init();
102}