/*
 * Copyright (c) 2015-2017, ARM Limited and Contributors. All rights reserved.
 *
 * SPDX-License-Identifier: BSD-3-Clause
 */

#include <arch_helpers.h>
#include <assert.h>
#include <debug.h>
#include <memctrl.h>
#include <memctrl_v1.h>
#include <mmio.h>
#include <string.h>
#include <tegra_def.h>
#include <utils.h>
#include <xlat_tables_v2.h>

#define TEGRA_GPU_RESET_REG_OFFSET	0x28c
#define  GPU_RESET_BIT			(1 << 24)

/* Video Memory base and size (live values) */
static uint64_t video_mem_base;
static uint64_t video_mem_size;

/*
 * Init SMMU.
 */
void tegra_memctrl_setup(void)
{
	/*
	 * Setup the Memory controller to allow only secure accesses to
	 * the TZDRAM carveout
	 */
	INFO("Tegra Memory Controller (v1)\n");

	/* allow translations for all MC engines */
	tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_0_0,
			(unsigned int)MC_SMMU_TRANSLATION_ENABLE);
	tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_1_0,
			(unsigned int)MC_SMMU_TRANSLATION_ENABLE);
	tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_2_0,
			(unsigned int)MC_SMMU_TRANSLATION_ENABLE);
	tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_3_0,
			(unsigned int)MC_SMMU_TRANSLATION_ENABLE);
	tegra_mc_write_32(MC_SMMU_TRANSLATION_ENABLE_4_0,
			(unsigned int)MC_SMMU_TRANSLATION_ENABLE);

	tegra_mc_write_32(MC_SMMU_ASID_SECURITY_0, MC_SMMU_ASID_SECURITY);

	tegra_mc_write_32(MC_SMMU_TLB_CONFIG_0, MC_SMMU_TLB_CONFIG_0_RESET_VAL);
	tegra_mc_write_32(MC_SMMU_PTC_CONFIG_0, MC_SMMU_PTC_CONFIG_0_RESET_VAL);

	/* flush PTC and TLB */
	tegra_mc_write_32(MC_SMMU_PTC_FLUSH_0, MC_SMMU_PTC_FLUSH_ALL);
	(void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */
	tegra_mc_write_32(MC_SMMU_TLB_FLUSH_0, MC_SMMU_TLB_FLUSH_ALL);

	/* enable SMMU */
	tegra_mc_write_32(MC_SMMU_CONFIG_0,
			  MC_SMMU_CONFIG_0_SMMU_ENABLE_ENABLE);
	(void)tegra_mc_read_32(MC_SMMU_CONFIG_0); /* read to flush writes */

	/* video memory carveout */
	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI,
			  (uint32_t)(video_mem_base >> 32));
	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)video_mem_base);
	tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, video_mem_size);
}

/*
 * Restore Memory Controller settings after "System Suspend"
 */
void tegra_memctrl_restore_settings(void)
{
	tegra_memctrl_setup();
}

/*
 * Secure the BL31 DRAM aperture.
 *
 * phys_base = physical base of TZDRAM aperture
 * size_in_bytes = size of aperture in bytes
 */
void tegra_memctrl_tzdram_setup(uint64_t phys_base, uint32_t size_in_bytes)
{
	/*
	 * Setup the Memory controller to allow only secure accesses to
	 * the TZDRAM carveout
	 */
	INFO("Configuring TrustZone DRAM Memory Carveout\n");

	tegra_mc_write_32(MC_SECURITY_CFG0_0, phys_base);
	tegra_mc_write_32(MC_SECURITY_CFG1_0, size_in_bytes >> 20);
}

/*
 * Secure the BL31 TZRAM aperture.
 *
 * phys_base = physical base of TZRAM aperture
 * size_in_bytes = size of aperture in bytes
 */
void tegra_memctrl_tzram_setup(uint64_t phys_base, uint32_t size_in_bytes)
{
	/*
	 * The v1 hardware controller does not have any registers
	 * for setting up the on-chip TZRAM.
	 */
}

static void tegra_clear_videomem(uintptr_t non_overlap_area_start,
				 unsigned long long non_overlap_area_size)
{
	/*
	 * Map the NS memory first, clean it and then unmap it.
	 */
	mmap_add_dynamic_region(non_overlap_area_start, /* PA */
				non_overlap_area_start, /* VA */
				non_overlap_area_size, /* size */
				MT_NS | MT_RW | MT_EXECUTE_NEVER); /* attrs */

	zeromem((void *)non_overlap_area_start, non_overlap_area_size);
	flush_dcache_range(non_overlap_area_start, non_overlap_area_size);

	mmap_remove_dynamic_region(non_overlap_area_start,
		non_overlap_area_size);
}

/*
 * Program the Video Memory carveout region
 *
 * phys_base = physical base of aperture
 * size_in_bytes = size of aperture in bytes
 */
void tegra_memctrl_videomem_setup(uint64_t phys_base, uint32_t size_in_bytes)
{
	uintptr_t vmem_end_old = video_mem_base + (video_mem_size << 20);
	uintptr_t vmem_end_new = phys_base + size_in_bytes;
	uint32_t regval;
	unsigned long long non_overlap_area_size;

	/*
	 * The GPU is the user of the Video Memory region. In order to
	 * transition to the new memory region smoothly, we program the
	 * new base/size ONLY if the GPU is in reset mode.
	 */
	regval = mmio_read_32(TEGRA_CAR_RESET_BASE + TEGRA_GPU_RESET_REG_OFFSET);
	if ((regval & GPU_RESET_BIT) == 0) {
		ERROR("GPU not in reset! Video Memory setup failed\n");
		return;
	}

	/*
	 * Setup the Memory controller to restrict CPU accesses to the Video
	 * Memory region
	 */
	INFO("Configuring Video Memory Carveout\n");

	/*
	 * Configure Memory Controller directly for the first time.
	 */
	if (video_mem_base == 0)
		goto done;

	/*
	 * Clear the old regions now being exposed. The following cases
	 * can occur -
	 *
	 * 1. clear whole old region (no overlap with new region)
	 * 2. clear old sub-region below new base
	 * 3. clear old sub-region above new end
	 */
	INFO("Cleaning previous Video Memory Carveout\n");

	if (phys_base > vmem_end_old || video_mem_base > vmem_end_new) {
		tegra_clear_videomem(video_mem_base, video_mem_size << 20);
	} else {
		if (video_mem_base < phys_base) {
			non_overlap_area_size = phys_base - video_mem_base;
			tegra_clear_videomem(video_mem_base, non_overlap_area_size);
		}
		if (vmem_end_old > vmem_end_new) {
			non_overlap_area_size = vmem_end_old - vmem_end_new;
			tegra_clear_videomem(vmem_end_new, non_overlap_area_size);
		}
	}

done:
	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_HI, (uint32_t)(phys_base >> 32));
	tegra_mc_write_32(MC_VIDEO_PROTECT_BASE_LO, (uint32_t)phys_base);
	tegra_mc_write_32(MC_VIDEO_PROTECT_SIZE_MB, size_in_bytes >> 20);

	/* store new values */
	video_mem_base = phys_base;
	video_mem_size = size_in_bytes >> 20;
}

/*
 * During boot, USB3 and flash media (SDMMC/SATA) devices need access to
 * IRAM. Because these clients connect to the MC and do not have a direct
 * path to the IRAM, the MC implements AHB redirection during boot to allow
 * path to IRAM. In this mode, accesses to a programmed memory address aperture
 * are directed to the AHB bus, allowing access to the IRAM. The AHB aperture
 * is defined by the IRAM_BASE_LO and IRAM_BASE_HI registers, which are
 * initialized to disable this aperture.
 *
 * Once bootup is complete, we must program IRAM base to 0xffffffff and
 * IRAM top to 0x00000000, thus disabling access to IRAM. DRAM is then
 * potentially accessible in this address range. These aperture registers
 * also have an access_control/lock bit. After disabling the aperture, the
 * access_control register should be programmed to lock the registers.
 */
void tegra_memctrl_disable_ahb_redirection(void)
{
	/* program the aperture registers */
	tegra_mc_write_32(MC_IRAM_BASE_LO, 0xFFFFFFFF);
	tegra_mc_write_32(MC_IRAM_TOP_LO, 0);
	tegra_mc_write_32(MC_IRAM_BASE_TOP_HI, 0);

	/* lock the aperture registers */
	tegra_mc_write_32(MC_IRAM_REG_CTRL, MC_DISABLE_IRAM_CFG_WRITES);
}
