blob: 80a2c4d0cc9b35bcbcd821cdcf9bb293a0000fc7 [file] [log] [blame]
Varun Wadekar7a269e22015-06-10 14:04:32 +05301/*
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -08002 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
Varun Wadekar76afaac2018-05-17 10:14:30 -07003 * Copyright (c) 2020, NVIDIA Corporation. All rights reserved.
Varun Wadekar7a269e22015-06-10 14:04:32 +05304 *
dp-armfa3cf0b2017-05-03 09:38:09 +01005 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekar7a269e22015-06-10 14:04:32 +05306 */
7
Varun Wadekar7a269e22015-06-10 14:04:32 +05308#include <assert.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +05309#include <errno.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +000010
11#include <arch.h>
12#include <arch_helpers.h>
13#include <common/bl_common.h>
14#include <common/debug.h>
15#include <common/runtime_svc.h>
16#include <lib/mmio.h>
17
Varun Wadekar7a269e22015-06-10 14:04:32 +053018#include <memctrl.h>
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -080019#include <tegra_platform.h>
Isla Mitchelle3631462017-07-14 10:46:32 +010020#include <tegra_private.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +053021
Varun Wadekar0f3baa02015-07-16 11:36:33 +053022/*******************************************************************************
Varun Wadekar923d04a2015-12-09 18:18:53 -080023 * Common Tegra SiP SMCs
Varun Wadekar0f3baa02015-07-16 11:36:33 +053024 ******************************************************************************/
Varun Wadekar7a269e22015-06-10 14:04:32 +053025#define TEGRA_SIP_NEW_VIDEOMEM_REGION 0x82000003
Varun Wadekardc799302015-12-28 16:36:42 -080026#define TEGRA_SIP_FIQ_NS_ENTRYPOINT 0x82000005
27#define TEGRA_SIP_FIQ_NS_GET_CONTEXT 0x82000006
Varun Wadekar7a269e22015-06-10 14:04:32 +053028
29/*******************************************************************************
Wayne Lin2330edd2016-03-31 13:49:09 -070030 * This function is responsible for handling all SiP calls
Varun Wadekar7a269e22015-06-10 14:04:32 +053031 ******************************************************************************/
Masahiro Yamada5ac9d962018-04-19 01:18:48 +090032uintptr_t tegra_sip_handler(uint32_t smc_fid,
33 u_register_t x1,
34 u_register_t x2,
35 u_register_t x3,
36 u_register_t x4,
37 void *cookie,
38 void *handle,
39 u_register_t flags)
Varun Wadekar7a269e22015-06-10 14:04:32 +053040{
Anthony Zhou4408e882017-07-07 14:29:51 +080041 uint32_t regval, local_x2_32 = (uint32_t)x2;
Anthony Zhoue5bd3452017-03-01 12:47:37 +080042 int32_t err;
Varun Wadekar7a269e22015-06-10 14:04:32 +053043
Varun Wadekar923d04a2015-12-09 18:18:53 -080044 /* Check if this is a SoC specific SiP */
45 err = plat_sip_handler(smc_fid, x1, x2, x3, x4, cookie, handle, flags);
Anthony Zhou035f24b2017-03-01 12:47:37 +080046 if (err == 0) {
47
Varun Wadekar14f39572017-04-17 11:54:33 -070048 SMC_RET1(handle, (uint64_t)err);
Varun Wadekar923d04a2015-12-09 18:18:53 -080049
Anthony Zhou035f24b2017-03-01 12:47:37 +080050 } else {
Varun Wadekar7a269e22015-06-10 14:04:32 +053051
Anthony Zhou035f24b2017-03-01 12:47:37 +080052 switch (smc_fid) {
Varun Wadekar7a269e22015-06-10 14:04:32 +053053
Anthony Zhou035f24b2017-03-01 12:47:37 +080054 case TEGRA_SIP_NEW_VIDEOMEM_REGION:
Anthony Zhou41eac8a2019-12-04 14:58:23 +080055 /* Check whether Video memory resize is enabled */
56 if (mmio_read_32(TEGRA_MC_BASE + MC_VIDEO_PROTECT_REG_CTRL)
57 != MC_VIDEO_PROTECT_WRITE_ACCESS_ENABLED) {
58 ERROR("Video Memory Resize isn't enabled! \n");
59 SMC_RET1(handle, (uint64_t)-ENOTSUP);
60 }
Varun Wadekar0f3baa02015-07-16 11:36:33 +053061
Anthony Zhou035f24b2017-03-01 12:47:37 +080062 /*
63 * Check if Video Memory overlaps TZDRAM (contains bl31/bl32)
64 * or falls outside of the valid DRAM range
65 */
Anthony Zhou4408e882017-07-07 14:29:51 +080066 err = bl31_check_ns_address(x1, local_x2_32);
Anthony Zhou035f24b2017-03-01 12:47:37 +080067 if (err != 0) {
68 SMC_RET1(handle, (uint64_t)err);
69 }
Varun Wadekara59a7c52017-04-26 08:31:50 -070070
Anthony Zhou035f24b2017-03-01 12:47:37 +080071 /*
72 * Check if Video Memory is aligned to 1MB.
73 */
Anthony Zhou4408e882017-07-07 14:29:51 +080074 if (((x1 & 0xFFFFFU) != 0U) || ((local_x2_32 & 0xFFFFFU) != 0U)) {
Anthony Zhou035f24b2017-03-01 12:47:37 +080075 ERROR("Unaligned Video Memory base address!\n");
Anthony Zhou0e07e452017-07-26 17:16:54 +080076 SMC_RET1(handle, (uint64_t)-ENOTSUP);
Anthony Zhou035f24b2017-03-01 12:47:37 +080077 }
Varun Wadekar7a269e22015-06-10 14:04:32 +053078
Anthony Zhou035f24b2017-03-01 12:47:37 +080079 /*
80 * The GPU is the user of the Video Memory region. In order to
81 * transition to the new memory region smoothly, we program the
82 * new base/size ONLY if the GPU is in reset mode.
83 */
84 regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
85 TEGRA_GPU_RESET_REG_OFFSET);
Anthony Zhou0e07e452017-07-26 17:16:54 +080086 if ((regval & GPU_RESET_BIT) == 0U) {
Anthony Zhou035f24b2017-03-01 12:47:37 +080087 ERROR("GPU not in reset! Video Memory setup failed\n");
Anthony Zhou0e07e452017-07-26 17:16:54 +080088 SMC_RET1(handle, (uint64_t)-ENOTSUP);
Anthony Zhou035f24b2017-03-01 12:47:37 +080089 }
Varun Wadekar7a269e22015-06-10 14:04:32 +053090
Anthony Zhou035f24b2017-03-01 12:47:37 +080091 /* new video memory carveout settings */
Anthony Zhou4408e882017-07-07 14:29:51 +080092 tegra_memctrl_videomem_setup(x1, local_x2_32);
Varun Wadekardc799302015-12-28 16:36:42 -080093
Jeetesh Burman48fef882018-01-22 15:40:08 +053094 /*
95 * Ensure again that GPU is still in reset after VPR resize
96 */
97 regval = mmio_read_32(TEGRA_CAR_RESET_BASE +
98 TEGRA_GPU_RESET_REG_OFFSET);
99 if ((regval & GPU_RESET_BIT) == 0U) {
100 mmio_write_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_GPU_SET_OFFSET,
101 GPU_SET_BIT);
102 }
103
Anthony Zhou035f24b2017-03-01 12:47:37 +0800104 SMC_RET1(handle, 0);
Varun Wadekardc799302015-12-28 16:36:42 -0800105
106 /*
Anthony Zhou035f24b2017-03-01 12:47:37 +0800107 * The NS world registers the address of its handler to be
108 * used for processing the FIQ. This is normally used by the
109 * NS FIQ debugger driver to detect system hangs by programming
110 * a watchdog timer to fire a FIQ interrupt.
Varun Wadekardc799302015-12-28 16:36:42 -0800111 */
Anthony Zhou035f24b2017-03-01 12:47:37 +0800112 case TEGRA_SIP_FIQ_NS_ENTRYPOINT:
Varun Wadekardc799302015-12-28 16:36:42 -0800113
Anthony Zhou035f24b2017-03-01 12:47:37 +0800114 if (x1 == 0U) {
115 SMC_RET1(handle, SMC_UNK);
116 }
Varun Wadekardc799302015-12-28 16:36:42 -0800117
Anthony Zhou035f24b2017-03-01 12:47:37 +0800118 /*
119 * TODO: Check if x1 contains a valid DRAM address
120 */
Varun Wadekardc799302015-12-28 16:36:42 -0800121
Anthony Zhou035f24b2017-03-01 12:47:37 +0800122 /* store the NS world's entrypoint */
123 tegra_fiq_set_ns_entrypoint(x1);
Varun Wadekardc799302015-12-28 16:36:42 -0800124
Anthony Zhou035f24b2017-03-01 12:47:37 +0800125 SMC_RET1(handle, 0);
Varun Wadekardc799302015-12-28 16:36:42 -0800126
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -0800127 /*
Anthony Zhou035f24b2017-03-01 12:47:37 +0800128 * The NS world's FIQ handler issues this SMC to get the NS EL1/EL0
129 * CPU context when the FIQ interrupt was triggered. This allows the
130 * NS world to understand the CPU state when the watchdog interrupt
131 * triggered.
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -0800132 */
Anthony Zhou035f24b2017-03-01 12:47:37 +0800133 case TEGRA_SIP_FIQ_NS_GET_CONTEXT:
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -0800134
Anthony Zhou035f24b2017-03-01 12:47:37 +0800135 /* retrieve context registers when FIQ triggered */
136 (void)tegra_fiq_get_intr_context();
Vignesh Radhakrishnanb4a72942017-03-03 10:58:05 -0800137
Anthony Zhou035f24b2017-03-01 12:47:37 +0800138 SMC_RET0(handle);
139
Anthony Zhou035f24b2017-03-01 12:47:37 +0800140 default:
141 ERROR("%s: unhandled SMC (0x%x)\n", __func__, smc_fid);
142 break;
143 }
Varun Wadekar7a269e22015-06-10 14:04:32 +0530144 }
145
146 SMC_RET1(handle, SMC_UNK);
147}
148
149/* Define a runtime service descriptor for fast SMC calls */
150DECLARE_RT_SVC(
Varun Wadekar923d04a2015-12-09 18:18:53 -0800151 tegra_sip_fast,
Varun Wadekar7a269e22015-06-10 14:04:32 +0530152
Anthony Zhoue5bd3452017-03-01 12:47:37 +0800153 (OEN_SIP_START),
154 (OEN_SIP_END),
155 (SMC_TYPE_FAST),
156 (NULL),
157 (tegra_sip_handler)
Varun Wadekar7a269e22015-06-10 14:04:32 +0530158);