blob: e13818f2996f3c38e5ae122c368195843325d678 [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 <css_def.h>
Dan Handley9df48042015-03-19 18:58:55 +000016#include <plat_arm.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000017
Dan Handley9df48042015-03-19 18:58:55 +000018#include "css_mhu.h"
19
20/* SCP MHU secure channel registers */
21#define SCP_INTR_S_STAT 0x200
22#define SCP_INTR_S_SET 0x208
23#define SCP_INTR_S_CLEAR 0x210
24
25/* CPU MHU secure channel registers */
26#define CPU_INTR_S_STAT 0x300
27#define CPU_INTR_S_SET 0x308
28#define CPU_INTR_S_CLEAR 0x310
29
Jeenu Viswambharan749d25b2017-08-23 14:12:59 +010030ARM_INSTANTIATE_LOCK;
Dan Handley9df48042015-03-19 18:58:55 +000031
32/* Weak definition may be overridden in specific CSS based platform */
33#pragma weak plat_arm_pwrc_setup
34
35
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000036/*
37 * Slot 31 is reserved because the MHU hardware uses this register bit to
38 * indicate a non-secure access attempt. The total number of available slots is
39 * therefore 31 [30:0].
40 */
41#define MHU_MAX_SLOT_ID 30
42
43void mhu_secure_message_start(unsigned int slot_id)
Dan Handley9df48042015-03-19 18:58:55 +000044{
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000045 assert(slot_id <= MHU_MAX_SLOT_ID);
46
Dan Handley9df48042015-03-19 18:58:55 +000047 arm_lock_get();
48
49 /* Make sure any previous command has finished */
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000050 while (mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) &
51 (1 << slot_id))
Dan Handley9df48042015-03-19 18:58:55 +000052 ;
53}
54
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000055void mhu_secure_message_send(unsigned int slot_id)
Dan Handley9df48042015-03-19 18:58:55 +000056{
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000057 assert(slot_id <= MHU_MAX_SLOT_ID);
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000058 assert(!(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) &
59 (1 << slot_id)));
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000060
61 /* Send command to SCP */
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000062 mmio_write_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_SET, 1 << slot_id);
Dan Handley9df48042015-03-19 18:58:55 +000063}
64
65uint32_t mhu_secure_message_wait(void)
66{
67 /* Wait for response from SCP */
68 uint32_t response;
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000069 while (!(response = mmio_read_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_STAT)))
Dan Handley9df48042015-03-19 18:58:55 +000070 ;
71
72 return response;
73}
74
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000075void mhu_secure_message_end(unsigned int slot_id)
Dan Handley9df48042015-03-19 18:58:55 +000076{
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000077 assert(slot_id <= MHU_MAX_SLOT_ID);
78
Dan Handley9df48042015-03-19 18:58:55 +000079 /*
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000080 * Clear any response we got by writing one in the relevant slot bit to
81 * the CLEAR register
Dan Handley9df48042015-03-19 18:58:55 +000082 */
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000083 mmio_write_32(PLAT_CSS_MHU_BASE + SCP_INTR_S_CLEAR, 1 << slot_id);
Dan Handley9df48042015-03-19 18:58:55 +000084
85 arm_lock_release();
86}
87
Daniel Boulbyf45a4bb2018-09-18 13:26:03 +010088void __init mhu_secure_init(void)
Dan Handley9df48042015-03-19 18:58:55 +000089{
90 arm_lock_init();
91
92 /*
Sandrine Bailleux04b66d82015-03-18 14:52:53 +000093 * The STAT register resets to zero. Ensure it is in the expected state,
94 * as a stale or garbage value would make us think it's a message we've
95 * already sent.
Dan Handley9df48042015-03-19 18:58:55 +000096 */
Vikram Kanigiri5d86f2e2016-01-21 14:08:15 +000097 assert(mmio_read_32(PLAT_CSS_MHU_BASE + CPU_INTR_S_STAT) == 0);
Dan Handley9df48042015-03-19 18:58:55 +000098}
99
Daniel Boulbyf45a4bb2018-09-18 13:26:03 +0100100void __init plat_arm_pwrc_setup(void)
Dan Handley9df48042015-03-19 18:58:55 +0000101{
102 mhu_secure_init();
103}