1e2469d82SVarun Wadekar /* 2e2469d82SVarun Wadekar * Copyright (c) 2015-2019, ARM Limited and Contributors. All rights reserved. 3*66e0b947SVarun Wadekar * Copyright (c) 2020, NVIDIA Corporation. All rights reserved. 4e2469d82SVarun Wadekar * 5e2469d82SVarun Wadekar * SPDX-License-Identifier: BSD-3-Clause 6e2469d82SVarun Wadekar */ 7e2469d82SVarun Wadekar 8e2469d82SVarun Wadekar #include <assert.h> 9e2469d82SVarun Wadekar #include <string.h> 10e2469d82SVarun Wadekar 11e2469d82SVarun Wadekar #include <arch_helpers.h> 12e2469d82SVarun Wadekar #include <common/debug.h> 13e2469d82SVarun Wadekar #include <lib/mmio.h> 14e2469d82SVarun Wadekar #include <lib/utils.h> 15e2469d82SVarun Wadekar #include <lib/xlat_tables/xlat_tables_v2.h> 16e2469d82SVarun Wadekar 17e2469d82SVarun Wadekar #include <memctrl.h> 18e2469d82SVarun Wadekar #include <memctrl_v1.h> 19e2469d82SVarun Wadekar #include <tegra_def.h> 20e2469d82SVarun Wadekar 21e2469d82SVarun Wadekar /* Video Memory base and size (live values) */ 22e2469d82SVarun Wadekar static uint64_t video_mem_base; 23e2469d82SVarun Wadekar static uint64_t video_mem_size; 24e2469d82SVarun Wadekar 25e2469d82SVarun Wadekar /* 26e2469d82SVarun Wadekar * Init SMMU. 27e2469d82SVarun Wadekar */ 28e2469d82SVarun Wadekar void tegra_memctrl_setup(void) 29e2469d82SVarun Wadekar { 30e2469d82SVarun Wadekar /* 31e2469d82SVarun Wadekar * Setup the Memory controller to allow only secure accesses to 32e2469d82SVarun Wadekar * the TZDRAM carveout 33e2469d82SVarun Wadekar */ 34e2469d82SVarun Wadekar INFO("Tegra Memory Controller (v1)\n"); 35e2469d82SVarun Wadekar 36e2469d82SVarun Wadekar /* allow translations for all MC engines */ 37e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_0_0, 38e2469d82SVarun Wadekar (unsigned int)MC_SMMU_TRANSLATION_ENABLE); 39e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_1_0, 40e2469d82SVarun Wadekar (unsigned int)MC_SMMU_TRANSLATION_ENABLE); 41e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_2_0, 42e2469d82SVarun Wadekar (unsigned int)MC_SMMU_TRANSLATION_ENABLE); 43e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_3_0, 44e2469d82SVarun Wadekar (unsigned int)MC_SMMU_TRANSLATION_ENABLE); 45e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_4_0, 46e2469d82SVarun Wadekar (unsigned int)MC_SMMU_TRANSLATION_ENABLE); 47e2469d82SVarun Wadekar 48e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_ASID_SECURITY_0, MC_SMMU_ASID_SECURITY); 49e2469d82SVarun Wadekar 50e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_TLB_CONFIG_0, MC_SMMU_TLB_CONFIG_0_RESET_VAL); 51e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_PTC_CONFIG_0, MC_SMMU_PTC_CONFIG_0_RESET_VAL); 52e2469d82SVarun Wadekar 53e2469d82SVarun Wadekar /* flush PTC and TLB */ 54e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_PTC_FLUSH_0, MC_SMMU_PTC_FLUSH_ALL); 55e2469d82SVarun Wadekar (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */ 56e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_TLB_FLUSH_0, MC_SMMU_TLB_FLUSH_ALL); 57e2469d82SVarun Wadekar 58e2469d82SVarun Wadekar /* enable SMMU */ 59e2469d82SVarun Wadekar tegra_mc_write_32(MC_SMMU_CONFIG_0, 60e2469d82SVarun Wadekar MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE); 61e2469d82SVarun Wadekar (void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */ 62e2469d82SVarun Wadekar 63e2469d82SVarun Wadekar /* video memory carveout */ 64e2469d82SVarun Wadekar tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, 65e2469d82SVarun Wadekar (uint32_t)(video_mem_base >> 32)); 66e2469d82SVarun Wadekar tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base); 67e2469d82SVarun Wadekar tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size); 68e2469d82SVarun Wadekar } 69e2469d82SVarun Wadekar 70e2469d82SVarun Wadekar /* 71e2469d82SVarun Wadekar * Restore Memory Controller settings after "System Suspend" 72e2469d82SVarun Wadekar */ 73e2469d82SVarun Wadekar void tegra_memctrl_restore_settings(void) 74e2469d82SVarun Wadekar { 75e2469d82SVarun Wadekar tegra_memctrl_setup(); 76e2469d82SVarun Wadekar } 77e2469d82SVarun Wadekar 78e2469d82SVarun Wadekar /* 79e2469d82SVarun Wadekar * Secure the BL31 DRAM aperture. 80e2469d82SVarun Wadekar * 81e2469d82SVarun Wadekar * phys_base = physical base of TZDRAM aperture 82e2469d82SVarun Wadekar * size_in_bytes = size of aperture in bytes 83e2469d82SVarun Wadekar */ 84e2469d82SVarun Wadekar void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes) 85e2469d82SVarun Wadekar { 86e2469d82SVarun Wadekar /* 87e2469d82SVarun Wadekar * Setup the Memory controller to allow only secure accesses to 88e2469d82SVarun Wadekar * the TZDRAM carveout 89e2469d82SVarun Wadekar */ 90e2469d82SVarun Wadekar INFO("Configuring TrustZone DRAM Memory Carveout\n"); 91e2469d82SVarun Wadekar 92e2469d82SVarun Wadekar tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base); 93e2469d82SVarun Wadekar tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20); 94e2469d82SVarun Wadekar } 95e2469d82SVarun Wadekar 96e2469d82SVarun Wadekar static void tegra_clear_videomem(uintptr_t non_overlap_area_start, 97e2469d82SVarun Wadekar unsigned long long non_overlap_area_size) 98e2469d82SVarun Wadekar { 99e2469d82SVarun Wadekar int ret; 100e2469d82SVarun Wadekar 101e2469d82SVarun Wadekar /* 102e2469d82SVarun Wadekar * Map the NS memory first, clean it and then unmap it. 103e2469d82SVarun Wadekar */ 104e2469d82SVarun Wadekar ret = mmap_add_dynamic_region(non_overlap_area_start, /* PA */ 105e2469d82SVarun Wadekar non_overlap_area_start, /* VA */ 106e2469d82SVarun Wadekar non_overlap_area_size, /* size */ 107e2469d82SVarun Wadekar MT_NS | MT_RW | MT_EXECUTE_NEVER | 108e2469d82SVarun Wadekar MT_NON_CACHEABLE); /* attrs */ 109e2469d82SVarun Wadekar assert(ret == 0); 110e2469d82SVarun Wadekar 111e2469d82SVarun Wadekar zeromem((void *)non_overlap_area_start, non_overlap_area_size); 112e2469d82SVarun Wadekar flush_dcache_range(non_overlap_area_start, non_overlap_area_size); 113e2469d82SVarun Wadekar 114e2469d82SVarun Wadekar mmap_remove_dynamic_region(non_overlap_area_start, 115e2469d82SVarun Wadekar non_overlap_area_size); 116e2469d82SVarun Wadekar } 117e2469d82SVarun Wadekar 118e2469d82SVarun Wadekar /* 119e2469d82SVarun Wadekar * Program the Video Memory carveout region 120e2469d82SVarun Wadekar * 121e2469d82SVarun Wadekar * phys_base = physical base of aperture 122e2469d82SVarun Wadekar * size_in_bytes = size of aperture in bytes 123e2469d82SVarun Wadekar */ 124e2469d82SVarun Wadekar void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes) 125e2469d82SVarun Wadekar { 126e2469d82SVarun Wadekar uintptr_t vmem_end_old = video_mem_base + (video_mem_size << 20); 127e2469d82SVarun Wadekar uintptr_t vmem_end_new = phys_base + size_in_bytes; 128e2469d82SVarun Wadekar unsigned long long non_overlap_area_size; 129e2469d82SVarun Wadekar 130e2469d82SVarun Wadekar /* 131e2469d82SVarun Wadekar * Setup the Memory controller to restrict CPU accesses to the Video 132e2469d82SVarun Wadekar * Memory region 133e2469d82SVarun Wadekar */ 134e2469d82SVarun Wadekar INFO("Configuring Video Memory Carveout\n"); 135e2469d82SVarun Wadekar 136e2469d82SVarun Wadekar /* 137e2469d82SVarun Wadekar * Configure Memory Controller directly for the first time. 138e2469d82SVarun Wadekar */ 139e2469d82SVarun Wadekar if (video_mem_base == 0) 140e2469d82SVarun Wadekar goto done; 141e2469d82SVarun Wadekar 142e2469d82SVarun Wadekar /* 143e2469d82SVarun Wadekar * Clear the old regions now being exposed. The following cases 144e2469d82SVarun Wadekar * can occur - 145e2469d82SVarun Wadekar * 146e2469d82SVarun Wadekar * 1. clear whole old region (no overlap with new region) 147e2469d82SVarun Wadekar * 2. clear old sub-region below new base 148e2469d82SVarun Wadekar * 3. clear old sub-region above new end 149e2469d82SVarun Wadekar */ 150e2469d82SVarun Wadekar INFO("Cleaning previous Video Memory Carveout\n"); 151e2469d82SVarun Wadekar 152e2469d82SVarun Wadekar if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) { 153e2469d82SVarun Wadekar tegra_clear_videomem(video_mem_base, video_mem_size << 20); 154e2469d82SVarun Wadekar } else { 155e2469d82SVarun Wadekar if (video_mem_base < phys_base) { 156e2469d82SVarun Wadekar non_overlap_area_size = phys_base - video_mem_base; 157e2469d82SVarun Wadekar tegra_clear_videomem(video_mem_base, non_overlap_area_size); 158e2469d82SVarun Wadekar } 159e2469d82SVarun Wadekar if (vmem_end_old > vmem_end_new) { 160e2469d82SVarun Wadekar non_overlap_area_size = vmem_end_old - vmem_end_new; 161e2469d82SVarun Wadekar tegra_clear_videomem(vmem_end_new, non_overlap_area_size); 162e2469d82SVarun Wadekar } 163e2469d82SVarun Wadekar } 164e2469d82SVarun Wadekar 165e2469d82SVarun Wadekar done: 166e2469d82SVarun Wadekar tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32)); 167e2469d82SVarun Wadekar tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base); 168e2469d82SVarun Wadekar tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20); 169e2469d82SVarun Wadekar 170e2469d82SVarun Wadekar /* store new values */ 171e2469d82SVarun Wadekar video_mem_base = phys_base; 172e2469d82SVarun Wadekar video_mem_size = size_in_bytes >> 20; 173e2469d82SVarun Wadekar } 174e2469d82SVarun Wadekar 175e2469d82SVarun Wadekar /* 176e2469d82SVarun Wadekar * During boot, USB3 and flash media (SDMMC/SATA) devices need access to 177e2469d82SVarun Wadekar * IRAM. Because these clients connect to the MC and do not have a direct 178e2469d82SVarun Wadekar * path to the IRAM, the MC implements AHB redirection during boot to allow 179e2469d82SVarun Wadekar * path to IRAM. In this mode, accesses to a programmed memory address aperture 180e2469d82SVarun Wadekar * are directed to the AHB bus, allowing access to the IRAM. The AHB aperture 181e2469d82SVarun Wadekar * is defined by the IRAM_BASE_LO and IRAM_BASE_HI registers, which are 182e2469d82SVarun Wadekar * initialized to disable this aperture. 183e2469d82SVarun Wadekar * 184e2469d82SVarun Wadekar * Once bootup is complete, we must program IRAM base to 0xffffffff and 185e2469d82SVarun Wadekar * IRAM top to 0x00000000, thus disabling access to IRAM. DRAM is then 186e2469d82SVarun Wadekar * potentially accessible in this address range. These aperture registers 187e2469d82SVarun Wadekar * also have an access_control/lock bit. After disabling the aperture, the 188e2469d82SVarun Wadekar * access_control register should be programmed to lock the registers. 189e2469d82SVarun Wadekar */ 190e2469d82SVarun Wadekar void tegra_memctrl_disable_ahb_redirection(void) 191e2469d82SVarun Wadekar { 192e2469d82SVarun Wadekar /* program the aperture registers */ 193e2469d82SVarun Wadekar tegra_mc_write_32(MC_IRAM_BASE_LO, 0xFFFFFFFF); 194e2469d82SVarun Wadekar tegra_mc_write_32(MC_IRAM_TOP_LO, 0); 195e2469d82SVarun Wadekar tegra_mc_write_32(MC_IRAM_BASE_TOP_HI, 0); 196e2469d82SVarun Wadekar 197e2469d82SVarun Wadekar /* lock the aperture registers */ 198e2469d82SVarun Wadekar tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES); 199e2469d82SVarun Wadekar } 200e2469d82SVarun Wadekar 201e2469d82SVarun Wadekar void tegra_memctrl_clear_pending_interrupts(void) 202e2469d82SVarun Wadekar { 203e2469d82SVarun Wadekar uint32_t mcerr; 204e2469d82SVarun Wadekar 205e2469d82SVarun Wadekar /* check if there are any pending interrupts */ 206e2469d82SVarun Wadekar mcerr = mmio_read_32(TEGRA_MC_BASE + MC_INTSTATUS); 207e2469d82SVarun Wadekar 208e2469d82SVarun Wadekar if (mcerr != (uint32_t)0U) { /* should not see error here */ 209e2469d82SVarun Wadekar WARN("MC_INTSTATUS = 0x%x (should be zero)\n", mcerr); 210e2469d82SVarun Wadekar mmio_write_32((TEGRA_MC_BASE + MC_INTSTATUS), mcerr); 211e2469d82SVarun Wadekar } 212e2469d82SVarun Wadekar } 213