blob: 2faefc8f6bda67c4460424d5cd40c479f4aef977 [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 *
dp-armfa3cf0b2017-05-03 09:38:09 +01004 * SPDX-License-Identifier: BSD-3-Clause
Varun Wadekarb316e242015-05-19 16:48:04 +05305 */
6
Varun Wadekar7a269e22015-06-10 14:04:32 +05307#include <arch_helpers.h>
Varun Wadekarb316e242015-05-19 16:48:04 +05308#include <assert.h>
9#include <debug.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053010#include <memctrl.h>
Varun Wadekar7a9a2852015-09-18 11:21:22 +053011#include <memctrl_v1.h>
12#include <mmio.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +053013#include <string.h>
Varun Wadekarb316e242015-05-19 16:48:04 +053014#include <tegra_def.h>
Douglas Raillarda8954fc2017-01-26 15:54:44 +000015#include <utils.h>
Varun Wadekarb5132322017-04-10 15:30:17 -070016#include <xlat_tables_v2.h>
Varun Wadekar7a269e22015-06-10 14:04:32 +053017
Varun Wadekar7a269e22015-06-10 14:04:32 +053018#define TEGRA_GPU_RESET_REG_OFFSET 0x28c
19#define GPU_RESET_BIT (1 << 24)
20
21/* Video Memory base and size (live values) */
Varun Wadekar64443ca2016-12-12 16:14:57 -080022static uint64_t video_mem_base;
Varun Wadekar7a269e22015-06-10 14:04:32 +053023static uint64_t video_mem_size;
Varun Wadekarb316e242015-05-19 16:48:04 +053024
25/*
26 * Init SMMU.
27 */
28void tegra_memctrl_setup(void)
29{
30 /*
31 * Setup the Memory controller to allow only secure accesses to
32 * the TZDRAM carveout
33 */
Varun Wadekar7a9a2852015-09-18 11:21:22 +053034 INFO("Tegra Memory Controller (v1)\n");
Varun Wadekarb316e242015-05-19 16:48:04 +053035
36 /* allow translations for all MC engines */
37 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_0_0,
38 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
39 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_1_0,
40 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
41 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_2_0,
42 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
43 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_3_0,
44 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
45 tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_4_0,
46 (unsigned int)MC_SMMU_TRANSLATION_ENABLE);
47
48 tegra_mc_write_32(MC_SMMU_ASID_SECURITY_0, MC_SMMU_ASID_SECURITY);
49
50 tegra_mc_write_32(MC_SMMU_TLB_CONFIG_0, MC_SMMU_TLB_CONFIG_0_RESET_VAL);
51 tegra_mc_write_32(MC_SMMU_PTC_CONFIG_0, MC_SMMU_PTC_CONFIG_0_RESET_VAL);
52
53 /* flush PTC and TLB */
54 tegra_mc_write_32(MC_SMMU_PTC_FLUSH_0, MC_SMMU_PTC_FLUSH_ALL);
55 (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */
56 tegra_mc_write_32(MC_SMMU_TLB_FLUSH_0, MC_SMMU_TLB_FLUSH_ALL);
57
58 /* enable SMMU */
59 tegra_mc_write_32(MC_SMMU_CONFIG_0,
60 MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE);
61 (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */
Varun Wadekar7a269e22015-06-10 14:04:32 +053062
63 /* video memory carveout */
Varun Wadekar64443ca2016-12-12 16:14:57 -080064 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
65 (uint32_t)(video_mem_base >> 32));
66 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base);
Varun Wadekar7a269e22015-06-10 14:04:32 +053067 tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size);
Varun Wadekarb316e242015-05-19 16:48:04 +053068}
69
70/*
Varun Wadekar6eec6d62016-03-03 13:28:10 -080071 * Restore Memory Controller settings after "System Suspend"
72 */
73void tegra_memctrl_restore_settings(void)
74{
75 tegra_memctrl_setup();
76}
77
78/*
Varun Wadekarb316e242015-05-19 16:48:04 +053079 * Secure the BL31 DRAM aperture.
80 *
81 * phys_base = physical base of TZDRAM aperture
82 * size_in_bytes = size of aperture in bytes
83 */
84void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
85{
86 /*
87 * Setup the Memory controller to allow only secure accesses to
88 * the TZDRAM carveout
89 */
90 INFO("Configuring TrustZone DRAM Memory Carveout\n");
91
92 tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base);
93 tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
94}
Varun Wadekar7a269e22015-06-10 14:04:32 +053095
Varun Wadekar0dc91812015-12-30 15:06:41 -080096/*
97 * Secure the BL31 TZRAM aperture.
98 *
99 * phys_base = physical base of TZRAM aperture
100 * size_in_bytes = size of aperture in bytes
101 */
102void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
103{
104 /*
105 * The v1 hardware controller does not have any registers
106 * for setting up the on-chip TZRAM.
107 */
108}
109
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100110static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
111 unsigned long long non_overlap_area_size)
112{
113 /*
Varun Wadekarb5132322017-04-10 15:30:17 -0700114 * Map the NS memory first, clean it and then unmap it.
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100115 */
Varun Wadekarb5132322017-04-10 15:30:17 -0700116 mmap_add_dynamic_region(non_overlap_area_start, /* PA */
117 non_overlap_area_start, /* VA */
118 non_overlap_area_size, /* size */
119 MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */
120
Douglas Raillard21362a92016-12-02 13:51:54 +0000121 zeromem((void *)non_overlap_area_start, non_overlap_area_size);
Varun Wadekarb5132322017-04-10 15:30:17 -0700122 flush_dcache_range(non_overlap_area_start, non_overlap_area_size);
123
124 mmap_remove_dynamic_region(non_overlap_area_start,
125 non_overlap_area_size);
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100126}
127
Varun Wadekar7a269e22015-06-10 14:04:32 +0530128/*
129 * Program the Video Memory carveout region
130 *
131 * phys_base = physical base of aperture
132 * size_in_bytes = size of aperture in bytes
133 */
134void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
135{
136 uintptr_t vmem_end_old = video_mem_base + (video_mem_size << 20);
137 uintptr_t vmem_end_new = phys_base + size_in_bytes;
138 uint32_t regval;
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100139 unsigned long long non_overlap_area_size;
Varun Wadekar7a269e22015-06-10 14:04:32 +0530140
141 /*
142 * The GPU is the user of the Video Memory region. In order to
143 * transition to the new memory region smoothly, we program the
144 * new base/size ONLY if the GPU is in reset mode.
145 */
146 regval = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET);
147 if ((regval & GPU_RESET_BIT) == 0) {
148 ERROR("GPU not in reset! Video Memory setup failed\n");
149 return;
150 }
151
152 /*
153 * Setup the Memory controller to restrict CPU accesses to the Video
154 * Memory region
155 */
156 INFO("Configuring Video Memory Carveout\n");
157
158 /*
159 * Configure Memory Controller directly for the first time.
160 */
161 if (video_mem_base == 0)
162 goto done;
163
164 /*
165 * Clear the old regions now being exposed. The following cases
166 * can occur -
167 *
168 * 1. clear whole old region (no overlap with new region)
169 * 2. clear old sub-region below new base
170 * 3. clear old sub-region above new end
171 */
172 INFO("Cleaning previous Video Memory Carveout\n");
173
Varun Wadekar1be2f972015-08-26 15:06:14 +0530174 if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) {
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100175 tegra_clear_videomem(video_mem_base, video_mem_size << 20);
Varun Wadekar1be2f972015-08-26 15:06:14 +0530176 } else {
177 if (video_mem_base < phys_base) {
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100178 non_overlap_area_size = phys_base - video_mem_base;
179 tegra_clear_videomem(video_mem_base, non_overlap_area_size);
Varun Wadekar1be2f972015-08-26 15:06:14 +0530180 }
181 if (vmem_end_old > vmem_end_new) {
Vikram Kanigiri4489ad12015-09-10 14:12:36 +0100182 non_overlap_area_size = vmem_end_old - vmem_end_new;
183 tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
Varun Wadekar1be2f972015-08-26 15:06:14 +0530184 }
185 }
Varun Wadekar7a269e22015-06-10 14:04:32 +0530186
187done:
Varun Wadekar64443ca2016-12-12 16:14:57 -0800188 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32));
189 tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base);
Varun Wadekar7a269e22015-06-10 14:04:32 +0530190 tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);
191
192 /* store new values */
193 video_mem_base = phys_base;
194 video_mem_size = size_in_bytes >> 20;
195}
Varun Wadekarc92050b2017-03-29 14:57:29 -0700196
197/*
198 * During boot, USB3 and flash media (SDMMC/SATA) devices need access to
199 * IRAM. Because these clients connect to the MC and do not have a direct
200 * path to the IRAM, the MC implements AHB redirection during boot to allow
201 * path to IRAM. In this mode, accesses to a programmed memory address aperture
202 * are directed to the AHB bus, allowing access to the IRAM. The AHB aperture
203 * is defined by the IRAM_BASE_LO and IRAM_BASE_HI registers, which are
204 * initialized to disable this aperture.
205 *
206 * Once bootup is complete, we must program IRAM base to 0xffffffff and
207 * IRAM top to 0x00000000, thus disabling access to IRAM. DRAM is then
208 * potentially accessible in this address range. These aperture registers
209 * also have an access_control/lock bit. After disabling the aperture, the
210 * access_control register should be programmed to lock the registers.
211 */
212void tegra_memctrl_disable_ahb_redirection(void)
213{
214 /* program the aperture registers */
215 tegra_mc_write_32(MC_IRAM_BASE_LO, 0xFFFFFFFF);
216 tegra_mc_write_32(MC_IRAM_TOP_LO, 0);
217 tegra_mc_write_32(MC_IRAM_BASE_TOP_HI, 0);
218
219 /* lock the aperture registers */
220 tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES);
221}