blob: a6a649b7a34034c9cd7783ab180aa9e008328b64 [file] [log] [blame]
Varun Wadekarb316e242015-05-19 16:48:04 +05301/*
Douglas Raillard21362a92016-12-02 13:51:54 +00002 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
Varun Wadekarb316e242015-05-19 16:48:04 +05303 *
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are met:
6 *
7 * Redistributions of source code must retain the above copyright notice, this
8 * list of conditions and the following disclaimer.
9 *
10 * Redistributions in binary form must reproduce the above copyright notice,
11 * this list of conditions and the following disclaimer in the documentation
12 * and/or other materials provided with the distribution.
13 *
14 * Neither the name of ARM nor the names of its contributors may be used
15 * to endorse or promote products derived from this software without specific
16 * prior written permission.
17 *
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
19 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
20 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
21 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
22 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
23 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
24 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
25 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
26 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
27 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
28 * POSSIBILITY OF SUCH DAMAGE.
29 */
30
Varun Wadekar7a269e22015-06-10 14:04:32 +053031#include <arch_helpers.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053032#include <assert.h>
33#include <debug.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053034#include <memctrl.h>
Varun Wadekar7a9a2852015-09-18 11:21:22 +053035#include <memctrl_v1.h>
36#include <mmio.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +053037#include <string.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053038#include <tegra_def.h>
Douglas Raillarda8954fc2017-01-26 15:54:44 +000039#include <utils.h>
Varun Wadekarb5132322017-04-10 15:30:17 -070040#include <xlat_tables_v2.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +053041
Varun Wadekar7a269e22015-06-10 14:04:32 +053042#define TEGRA_GPU_RESET_REG_OFFSET 0x28c
43#define GPU_RESET_BIT (1 << 24)
44
45/* Video Memory base and size (live values) */
Varun Wadekar64443ca2016-12-12 16:14:57 -080046static uint64_t video_mem_base;
Varun Wadekar7a269e22015-06-10 14:04:32 +053047static uint64_t video_mem_size;
Varun Wadekarb316e242015-05-19 16:48:04 +053048
49/*
50 * Init SMMU.
51 */
52void tegra_memctrl_setup(void)
53{
54 /*
55 * Setup the Memory controller to allow only secure accesses to
56 * the TZDRAM carveout
57 */
Varun Wadekar7a9a2852015-09-18 11:21:22 +053058 INFO("Tegra Memory Controller (v1)\n");
Varun Wadekarb316e242015-05-19 16:48:04 +053059
60 /* allow translations for all MC engines */
61 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_0_0,
62 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
63 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_1_0,
64 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
65 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_2_0,
66 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
67 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_3_0,
68 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
69 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_4_0,
70 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
71
72 tegra_mc_write_32(MC_SMMU_ASID_SECURITY_0, MC_SMMU_ASID_SECURITY);
73
74 tegra_mc_write_32(MC_SMMU_TLB_CONFIG_0, MC_SMMU_TLB_CONFIG_0_RESET_VAL);
75 tegra_mc_write_32(MC_SMMU_PTC_CONFIG_0, MC_SMMU_PTC_CONFIG_0_RESET_VAL);
76
77 /* flush PTC and TLB */
78 tegra_mc_write_32(MC_SMMU_PTC_FLUSH_0, MC_SMMU_PTC_FLUSH_ALL);
79 (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */
80 tegra_mc_write_32(MC_SMMU_TLB_FLUSH_0, MC_SMMU_TLB_FLUSH_ALL);
81
82 /* enable SMMU */
83 tegra_mc_write_32(MC_SMMU_CONFIG_0,
84 MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE);
85 (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */
Varun Wadekar7a269e22015-06-10 14:04:32 +053086
87 /* video memory carveout */
Varun Wadekar64443ca2016-12-12 16:14:57 -080088 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
89 (uint32_t)(video_mem_base >> 32));
90 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base);
Varun Wadekar7a269e22015-06-10 14:04:32 +053091 tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size);
Varun Wadekarb316e242015-05-19 16:48:04 +053092}
93
94/*
Varun Wadekar6eec6d62016-03-03 13:28:10 -080095 * Restore Memory Controller settings after "System Suspend"
96 */
97void tegra_memctrl_restore_settings(void)
98{
99 tegra_memctrl_setup();
100}
101
102/*
Varun Wadekarb316e242015-05-19 16:48:04 +0530103 * Secure the BL31 DRAM aperture.
104 *
105 * phys_base = physical base of TZDRAM aperture
106 * size_in_bytes = size of aperture in bytes
107 */
108void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
109{
110 /*
111 * Setup the Memory controller to allow only secure accesses to
112 * the TZDRAM carveout
113 */
114 INFO("Configuring TrustZone DRAM Memory Carveout\n");
115
116 tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base);
117 tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
118}
Varun Wadekar7a269e22015-06-10 14:04:32 +0530119
Varun Wadekar0dc91812015-12-30 15:06:41 -0800120/*
121 * Secure the BL31 TZRAM aperture.
122 *
123 * phys_base = physical base of TZRAM aperture
124 * size_in_bytes = size of aperture in bytes
125 */
126void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
127{
128 /*
129 * The v1 hardware controller does not have any registers
130 * for setting up the on-chip TZRAM.
131 */
132}
133
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100134static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
135 unsigned long long non_overlap_area_size)
136{
137 /*
Varun Wadekarb5132322017-04-10 15:30:17 -0700138 * Map the NS memory first, clean it and then unmap it.
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100139 */
Varun Wadekarb5132322017-04-10 15:30:17 -0700140 mmap_add_dynamic_region(non_overlap_area_start, /* PA */
141 non_overlap_area_start, /* VA */
142 non_overlap_area_size, /* size */
143 MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
144
Douglas Raillard21362a92016-12-02 13:51:54 +0000145 zeromem((void *)non_overlap_area_start, non_overlap_area_size);
Varun Wadekarb5132322017-04-10 15:30:17 -0700146 flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
147
148 mmap_remove_dynamic_region(non_overlap_area_start,
149 non_overlap_area_size);
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100150}
151
Varun Wadekar7a269e22015-06-10 14:04:32 +0530152/*
153 * Program the Video Memory carveout region
154 *
155 * phys_base = physical base of aperture
156 * size_in_bytes = size of aperture in bytes
157 */
158void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
159{
160 uintptr_t vmem_end_old = video_mem_base + (video_mem_size << 20);
161 uintptr_t vmem_end_new = phys_base + size_in_bytes;
162 uint32_t regval;
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100163 unsigned long long non_overlap_area_size;
Varun Wadekar7a269e22015-06-10 14:04:32 +0530164
165 /*
166 * The GPU is the user of the Video Memory region. In order to
167 * transition to the new memory region smoothly, we program the
168 * new base/size ONLY if the GPU is in reset mode.
169 */
170 regval = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET);
171 if ((regval & GPU_RESET_BIT) == 0) {
172 ERROR("GPU not in reset! Video Memory setup failed\n");
173 return;
174 }
175
176 /*
177 * Setup the Memory controller to restrict CPU accesses to the Video
178 * Memory region
179 */
180 INFO("Configuring Video Memory Carveout\n");
181
182 /*
183 * Configure Memory Controller directly for the first time.
184 */
185 if (video_mem_base == 0)
186 goto done;
187
188 /*
189 * Clear the old regions now being exposed. The following cases
190 * can occur -
191 *
192 * 1. clear whole old region (no overlap with new region)
193 * 2. clear old sub-region below new base
194 * 3. clear old sub-region above new end
195 */
196 INFO("Cleaning previous Video Memory Carveout\n");
197
Varun Wadekar1be2f972015-08-26 15:06:14 +0530198 if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) {
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100199 tegra_clear_videomem(video_mem_base, video_mem_size << 20);
Varun Wadekar1be2f972015-08-26 15:06:14 +0530200 } else {
201 if (video_mem_base < phys_base) {
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100202 non_overlap_area_size = phys_base - video_mem_base;
203 tegra_clear_videomem(video_mem_base, non_overlap_area_size);
Varun Wadekar1be2f972015-08-26 15:06:14 +0530204 }
205 if (vmem_end_old > vmem_end_new) {
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100206 non_overlap_area_size = vmem_end_old - vmem_end_new;
207 tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
Varun Wadekar1be2f972015-08-26 15:06:14 +0530208 }
209 }
Varun Wadekar7a269e22015-06-10 14:04:32 +0530210
211done:
Varun Wadekar64443ca2016-12-12 16:14:57 -0800212 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32));
213 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base);
Varun Wadekar7a269e22015-06-10 14:04:32 +0530214 tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);
215
216 /* store new values */
217 video_mem_base = phys_base;
218 video_mem_size = size_in_bytes >> 20;
219}