blob: c3f95db4dc5b5667a740e411274d45e68c5abe0e [file] [log] [blame]
Varun Wadekarb316e242015-05-19 16:48:04 +05301/*
Ken Chang9dfb91e2018-12-28 08:44:12 +08002 * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved.
Varun Wadekarb316e242015-05-19 16:48:04 +05303 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekarb316e242015-05-19 16:48:04 +05305 */
6
7#include <assert.h>
Antonio Nino Diaze0f90632018-12-14 00:18:21 +00008#include <string.h>
9
10#include <arch_helpers.h>
11#include <common/debug.h>
12#include <lib/mmio.h>
13#include <lib/utils.h>
14#include <lib/xlat_tables/xlat_tables_v2.h>
15
Varun Wadekarb316e242015-05-19 16:48:04 +053016#include <memctrl.h>
Varun Wadekar7a9a2852015-09-18 11:21:22 +053017#include <memctrl_v1.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053018#include <tegra_def.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +053019
Varun Wadekar7a269e22015-06-10 14:04:32 +053020/* Video Memory base and size (live values) */
Varun Wadekar64443ca2016-12-12 16:14:57 -080021static uint64_t video_mem_base;
Varun Wadekar7a269e22015-06-10 14:04:32 +053022static uint64_t video_mem_size;
Varun Wadekarb316e242015-05-19 16:48:04 +053023
24/*
25 * Init SMMU.
26 */
27void tegra_memctrl_setup(void)
28{
29 /*
30 * Setup the Memory controller to allow only secure accesses to
31 * the TZDRAM carveout
32 */
Varun Wadekar7a9a2852015-09-18 11:21:22 +053033 INFO("Tegra Memory Controller (v1)\n");
Varun Wadekarb316e242015-05-19 16:48:04 +053034
35 /* allow translations for all MC engines */
36 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_0_0,
37 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
38 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_1_0,
39 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
40 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_2_0,
41 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
42 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_3_0,
43 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
44 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_4_0,
45 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
46
47 tegra_mc_write_32(MC_SMMU_ASID_SECURITY_0, MC_SMMU_ASID_SECURITY);
48
49 tegra_mc_write_32(MC_SMMU_TLB_CONFIG_0, MC_SMMU_TLB_CONFIG_0_RESET_VAL);
50 tegra_mc_write_32(MC_SMMU_PTC_CONFIG_0, MC_SMMU_PTC_CONFIG_0_RESET_VAL);
51
52 /* flush PTC and TLB */
53 tegra_mc_write_32(MC_SMMU_PTC_FLUSH_0, MC_SMMU_PTC_FLUSH_ALL);
54 (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */
55 tegra_mc_write_32(MC_SMMU_TLB_FLUSH_0, MC_SMMU_TLB_FLUSH_ALL);
56
57 /* enable SMMU */
58 tegra_mc_write_32(MC_SMMU_CONFIG_0,
59 MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE);
60 (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */
Varun Wadekar7a269e22015-06-10 14:04:32 +053061
62 /* video memory carveout */
Varun Wadekar64443ca2016-12-12 16:14:57 -080063 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
64 (uint32_t)(video_mem_base >> 32));
65 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base);
Varun Wadekar7a269e22015-06-10 14:04:32 +053066 tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size);
Varun Wadekarb316e242015-05-19 16:48:04 +053067}
68
69/*
Varun Wadekar6eec6d62016-03-03 13:28:10 -080070 * Restore Memory Controller settings after "System Suspend"
71 */
72void tegra_memctrl_restore_settings(void)
73{
74 tegra_memctrl_setup();
75}
76
77/*
Varun Wadekarb316e242015-05-19 16:48:04 +053078 * Secure the BL31 DRAM aperture.
79 *
80 * phys_base = physical base of TZDRAM aperture
81 * size_in_bytes = size of aperture in bytes
82 */
83void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
84{
85 /*
86 * Setup the Memory controller to allow only secure accesses to
87 * the TZDRAM carveout
88 */
89 INFO("Configuring TrustZone DRAM Memory Carveout\n");
90
91 tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base);
92 tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
93}
Varun Wadekar7a269e22015-06-10 14:04:32 +053094
Varun Wadekar0dc91812015-12-30 15:06:41 -080095/*
96 * Secure the BL31 TZRAM aperture.
97 *
98 * phys_base = physical base of TZRAM aperture
99 * size_in_bytes = size of aperture in bytes
100 */
101void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
102{
103 /*
104 * The v1 hardware controller does not have any registers
105 * for setting up the on-chip TZRAM.
106 */
107}
108
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100109static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
110 unsigned long long non_overlap_area_size)
111{
Varun Wadekar117a2e02017-08-03 11:40:34 -0700112 int ret;
113
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100114 /*
Varun Wadekarb5132322017-04-10 15:30:17 -0700115 * Map the NS memory first, clean it and then unmap it.
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100116 */
Varun Wadekar117a2e02017-08-03 11:40:34 -0700117 ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */
Varun Wadekarb5132322017-04-10 15:30:17 -0700118 non_overlap_area_start, /* VA */
119 non_overlap_area_size, /* size */
Ken Chang9dfb91e2018-12-28 08:44:12 +0800120 MT_NS | MT_RW | MT_EXECUTE_NEVER |
121 MT_NON_CACHEABLE); /* attrs */
Varun Wadekar117a2e02017-08-03 11:40:34 -0700122 assert(ret == 0);
Varun Wadekarb5132322017-04-10 15:30:17 -0700123
Douglas Raillard21362a92016-12-02 13:51:54 +0000124 zeromem((void *)non_overlap_area_start, non_overlap_area_size);
Varun Wadekarb5132322017-04-10 15:30:17 -0700125 flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
126
127 mmap_remove_dynamic_region(non_overlap_area_start,
128 non_overlap_area_size);
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100129}
130
Varun Wadekar7a269e22015-06-10 14:04:32 +0530131/*
132 * Program the Video Memory carveout region
133 *
134 * phys_base = physical base of aperture
135 * size_in_bytes = size of aperture in bytes
136 */
137void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
138{
139 uintptr_t vmem_end_old = video_mem_base + (video_mem_size << 20);
140 uintptr_t vmem_end_new = phys_base + size_in_bytes;
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100141 unsigned long long non_overlap_area_size;
Varun Wadekar7a269e22015-06-10 14:04:32 +0530142
143 /*
Varun Wadekar7a269e22015-06-10 14:04:32 +0530144 * Setup the Memory controller to restrict CPU accesses to the Video
145 * Memory region
146 */
147 INFO("Configuring Video Memory Carveout\n");
148
149 /*
150 * Configure Memory Controller directly for the first time.
151 */
152 if (video_mem_base == 0)
153 goto done;
154
155 /*
156 * Clear the old regions now being exposed. The following cases
157 * can occur -
158 *
159 * 1. clear whole old region (no overlap with new region)
160 * 2. clear old sub-region below new base
161 * 3. clear old sub-region above new end
162 */
163 INFO("Cleaning previous Video Memory Carveout\n");
164
Varun Wadekar1be2f972015-08-26 15:06:14 +0530165 if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) {
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100166 tegra_clear_videomem(video_mem_base, video_mem_size << 20);
Varun Wadekar1be2f972015-08-26 15:06:14 +0530167 } else {
168 if (video_mem_base < phys_base) {
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100169 non_overlap_area_size = phys_base - video_mem_base;
170 tegra_clear_videomem(video_mem_base, non_overlap_area_size);
Varun Wadekar1be2f972015-08-26 15:06:14 +0530171 }
172 if (vmem_end_old > vmem_end_new) {
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100173 non_overlap_area_size = vmem_end_old - vmem_end_new;
174 tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
Varun Wadekar1be2f972015-08-26 15:06:14 +0530175 }
176 }
Varun Wadekar7a269e22015-06-10 14:04:32 +0530177
178done:
Varun Wadekar64443ca2016-12-12 16:14:57 -0800179 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32));
180 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base);
Varun Wadekar7a269e22015-06-10 14:04:32 +0530181 tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);
182
183 /* store new values */
184 video_mem_base = phys_base;
185 video_mem_size = size_in_bytes >> 20;
186}
Varun Wadekarc92050b2017-03-29 14:57:29 -0700187
188/*
189 * During boot, USB3 and flash media (SDMMC/SATA) devices need access to
190 * IRAM. Because these clients connect to the MC and do not have a direct
191 * path to the IRAM, the MC implements AHB redirection during boot to allow
192 * path to IRAM. In this mode, accesses to a programmed memory address aperture
193 * are directed to the AHB bus, allowing access to the IRAM. The AHB aperture
194 * is defined by the IRAM_BASE_LO and IRAM_BASE_HI registers, which are
195 * initialized to disable this aperture.
196 *
197 * Once bootup is complete, we must program IRAM base to 0xffffffff and
198 * IRAM top to 0x00000000, thus disabling access to IRAM. DRAM is then
199 * potentially accessible in this address range. These aperture registers
200 * also have an access_control/lock bit. After disabling the aperture, the
201 * access_control register should be programmed to lock the registers.
202 */
203void tegra_memctrl_disable_ahb_redirection(void)
204{
205 /* program the aperture registers */
206 tegra_mc_write_32(MC_IRAM_BASE_LO, 0xFFFFFFFF);
207 tegra_mc_write_32(MC_IRAM_TOP_LO, 0);
208 tegra_mc_write_32(MC_IRAM_BASE_TOP_HI, 0);
209
210 /* lock the aperture registers */
211 tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES);
212}
Harvey Hsieh359be952017-08-21 15:01:53 +0800213
214void tegra_memctrl_clear_pending_interrupts(void)
215{
216 uint32_t mcerr;
217
218 /* check if there are any pending interrupts */
219 mcerr = mmio_read_32(TEGRA_MC_BASE + MC_INTSTATUS);
220
221 if (mcerr != (uint32_t)0U) { /* should not see error here */
222 WARN("MC_INTSTATUS = 0x%x (should be zero)\n", mcerr);
223 mmio_write_32((TEGRA_MC_BASE + MC_INTSTATUS), mcerr);
224 }
225}