// SPDX-License-Identifier: BSD-2-Clause
/*
 * Copyright 2017 NXP
 */

#include <arm.h>
#include <arm32.h>
#include <console.h>
#include <io.h>
#include <imx.h>
#include <imx_pm.h>
#include <kernel/panic.h>
#include <kernel/pm_stubs.h>
#include <kernel/cache_helpers.h>
#include <mm/core_mmu.h>
#include <mm/core_memprot.h>
#include <mmdc.h>
#include <platform_config.h>
#include <sm/pm.h>
#include <sm/psci.h>
#include <sm/sm.h>
#include <string.h>

paddr_t iram_tbl_phys_addr = -1UL;
void *iram_tbl_virt_addr;

#define READ_DATA_FROM_HARDWARE		0

static uint32_t imx7d_ddrc_ddr3_setting[][2] = {
	{ 0x0, READ_DATA_FROM_HARDWARE },
	{ 0x1a0, READ_DATA_FROM_HARDWARE },
	{ 0x1a4, READ_DATA_FROM_HARDWARE },
	{ 0x1a8, READ_DATA_FROM_HARDWARE },
	{ 0x64, READ_DATA_FROM_HARDWARE },
	{ 0x490, READ_DATA_FROM_HARDWARE },
	{ 0xd0, READ_DATA_FROM_HARDWARE },
	{ 0xd4, READ_DATA_FROM_HARDWARE },
	{ 0xdc, READ_DATA_FROM_HARDWARE },
	{ 0xe0, READ_DATA_FROM_HARDWARE },
	{ 0xe4, READ_DATA_FROM_HARDWARE },
	{ 0xf4, READ_DATA_FROM_HARDWARE },
	{ 0x100, READ_DATA_FROM_HARDWARE },
	{ 0x104, READ_DATA_FROM_HARDWARE },
	{ 0x108, READ_DATA_FROM_HARDWARE },
	{ 0x10c, READ_DATA_FROM_HARDWARE },
	{ 0x110, READ_DATA_FROM_HARDWARE },
	{ 0x114, READ_DATA_FROM_HARDWARE },
	{ 0x120, READ_DATA_FROM_HARDWARE },
	{ 0x180, READ_DATA_FROM_HARDWARE },
	{ 0x190, READ_DATA_FROM_HARDWARE },
	{ 0x194, READ_DATA_FROM_HARDWARE },
	{ 0x200, READ_DATA_FROM_HARDWARE },
	{ 0x204, READ_DATA_FROM_HARDWARE },
	{ 0x214, READ_DATA_FROM_HARDWARE },
	{ 0x218, READ_DATA_FROM_HARDWARE },
	{ 0x240, READ_DATA_FROM_HARDWARE },
	{ 0x244, READ_DATA_FROM_HARDWARE },
};

static uint32_t imx7d_ddrc_phy_ddr3_setting[][2] = {
	{ 0x0, READ_DATA_FROM_HARDWARE },
	{ 0x4, READ_DATA_FROM_HARDWARE },
	{ 0x10, READ_DATA_FROM_HARDWARE },
	{ 0xb0, READ_DATA_FROM_HARDWARE },
	{ 0x9c, READ_DATA_FROM_HARDWARE },
	{ 0x7c, READ_DATA_FROM_HARDWARE },
	{ 0x80, READ_DATA_FROM_HARDWARE },
	{ 0x84, READ_DATA_FROM_HARDWARE },
	{ 0x88, READ_DATA_FROM_HARDWARE },
	{ 0x6c, READ_DATA_FROM_HARDWARE },
	{ 0x20, READ_DATA_FROM_HARDWARE },
	{ 0x30, READ_DATA_FROM_HARDWARE },
	{ 0x50, 0x01000010 },
	{ 0x50, 0x00000010 },
	{ 0xc0, 0x0e407304 },
	{ 0xc0, 0x0e447304 },
	{ 0xc0, 0x0e447306 },
	{ 0xc0, 0x0e447304 },
	{ 0xc0, 0x0e407306 },
};

static struct imx7_pm_data imx7d_pm_data_ddr3 = {
	.ddrc_num = ARRAY_SIZE(imx7d_ddrc_ddr3_setting),
	.ddrc_offset = imx7d_ddrc_ddr3_setting,
	.ddrc_phy_num = ARRAY_SIZE(imx7d_ddrc_phy_ddr3_setting),
	.ddrc_phy_offset = imx7d_ddrc_phy_ddr3_setting,
};

paddr_t phys_addr[] = {
	AIPS1_BASE, AIPS2_BASE, AIPS3_BASE
};

int pm_imx7_iram_tbl_init(void)
{
	uint32_t i;
	struct tee_mmap_region map;

	/* iram mmu translation table already initialized */
	if (iram_tbl_phys_addr != (-1UL))
		return 0;

	iram_tbl_phys_addr = TRUSTZONE_OCRAM_START + 16 * 1024;
	iram_tbl_virt_addr = phys_to_virt(iram_tbl_phys_addr,
					  MEM_AREA_TEE_COHERENT);

	/* 16KB */
	memset(iram_tbl_virt_addr, 0, 16 * 1024);

	for (i = 0; i < ARRAY_SIZE(phys_addr); i++) {
		map.pa = phys_addr[i];
		map.va = (vaddr_t)phys_to_virt(phys_addr[i], MEM_AREA_IO_SEC);
		map.region_size = CORE_MMU_PGDIR_SIZE;
		map.size = AIPS1_SIZE; /* 4M for AIPS1/2/3 */
		map.type = MEM_AREA_IO_SEC;
		map.attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_PRW |
			   TEE_MATTR_SECURE |
			   (TEE_MATTR_CACHE_NONCACHE << TEE_MATTR_CACHE_SHIFT);
		map_memarea_sections(&map, (uint32_t *)iram_tbl_virt_addr);
	}

	/* Note IRAM_S_BASE is not 1M aligned, so take care */
	map.pa = ROUNDDOWN(IRAM_S_BASE, CORE_MMU_PGDIR_SIZE);
	map.va = (vaddr_t)phys_to_virt(map.pa, MEM_AREA_TEE_COHERENT);
	map.region_size = CORE_MMU_PGDIR_SIZE;
	map.size = CORE_MMU_PGDIR_SIZE;
	map.type = MEM_AREA_TEE_COHERENT;
	map.attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_PRWX | TEE_MATTR_SECURE;
	map_memarea_sections(&map, (uint32_t *)iram_tbl_virt_addr);

	map.pa = GIC_BASE;
	map.va = (vaddr_t)phys_to_virt((paddr_t)GIC_BASE, MEM_AREA_IO_SEC);
	map.region_size = CORE_MMU_PGDIR_SIZE;
	map.size = CORE_MMU_PGDIR_SIZE;
	map.type = MEM_AREA_TEE_COHERENT;
	map.attr = TEE_MATTR_VALID_BLOCK | TEE_MATTR_PRW | TEE_MATTR_SECURE;
	map_memarea_sections(&map, (uint32_t *)iram_tbl_virt_addr);

	return 0;
}

int imx7_suspend_init(void)
{
	uint32_t i;
	uint32_t (*ddrc_offset_array)[2];
	uint32_t (*ddrc_phy_offset_array)[2];
	uint32_t suspend_ocram_base = core_mmu_get_va(TRUSTZONE_OCRAM_START +
						      SUSPEND_OCRAM_OFFSET,
						      MEM_AREA_TEE_COHERENT);
	struct imx7_pm_info *p = (struct imx7_pm_info *)suspend_ocram_base;
	struct imx7_pm_data *pm_data;

	pm_imx7_iram_tbl_init();

	dcache_op_level1(DCACHE_OP_CLEAN_INV);

	p->pa_base = TRUSTZONE_OCRAM_START + SUSPEND_OCRAM_OFFSET;
	p->tee_resume = virt_to_phys((void *)(vaddr_t)ca7_cpu_resume);
	p->pm_info_size = sizeof(*p);
	p->ccm_va_base = core_mmu_get_va(CCM_BASE, MEM_AREA_IO_SEC);
	p->ccm_pa_base = CCM_BASE;
	p->ddrc_va_base = core_mmu_get_va(DDRC_BASE, MEM_AREA_IO_SEC);
	p->ddrc_pa_base = DDRC_BASE;
	p->ddrc_phy_va_base = core_mmu_get_va(DDRC_PHY_BASE, MEM_AREA_IO_SEC);
	p->ddrc_phy_pa_base = DDRC_PHY_BASE;
	p->src_va_base = core_mmu_get_va(SRC_BASE, MEM_AREA_IO_SEC);
	p->src_pa_base = SRC_BASE;
	p->iomuxc_gpr_va_base = core_mmu_get_va(IOMUXC_GPR_BASE,
						MEM_AREA_IO_SEC);
	p->iomuxc_gpr_pa_base = IOMUXC_GPR_BASE;
	p->gpc_va_base = core_mmu_get_va(GPC_BASE, MEM_AREA_IO_SEC);
	p->gpc_pa_base = GPC_BASE;
	p->anatop_va_base = core_mmu_get_va(ANATOP_BASE, MEM_AREA_IO_SEC);
	p->anatop_pa_base = ANATOP_BASE;
	p->snvs_va_base = core_mmu_get_va(SNVS_BASE, MEM_AREA_IO_SEC);
	p->snvs_pa_base = SNVS_BASE;
	p->lpsr_va_base = core_mmu_get_va(LPSR_BASE, MEM_AREA_IO_SEC);
	p->lpsr_pa_base = LPSR_BASE;
	p->gic_va_base = core_mmu_get_va(GIC_BASE, MEM_AREA_IO_SEC);
	p->gic_pa_base = GIC_BASE;

	/* TODO:lpsr disabled now */
	io_write32(p->lpsr_va_base, 0);

	p->ddr_type = imx_get_ddr_type();
	switch (p->ddr_type) {
	case IMX_DDR_TYPE_DDR3:
		pm_data = &imx7d_pm_data_ddr3;
		break;
	default:
		panic("Not supported ddr type\n");
		break;
	}

	p->ddrc_num = pm_data->ddrc_num;
	p->ddrc_phy_num = pm_data->ddrc_phy_num;
	ddrc_offset_array = pm_data->ddrc_offset;
	ddrc_phy_offset_array = pm_data->ddrc_phy_offset;

	for (i = 0; i < p->ddrc_num; i++) {
		p->ddrc_val[i][0] = ddrc_offset_array[i][0];
		if (ddrc_offset_array[i][1] == READ_DATA_FROM_HARDWARE)
			p->ddrc_val[i][1] = io_read32(p->ddrc_va_base +
						      ddrc_offset_array[i][0]);
		else
			p->ddrc_val[i][1] = ddrc_offset_array[i][1];

		if (p->ddrc_val[i][0] == 0xd0)
			p->ddrc_val[i][1] |= 0xc0000000;
	}

	/* initialize DDRC PHY settings */
	for (i = 0; i < p->ddrc_phy_num; i++) {
		p->ddrc_phy_val[i][0] = ddrc_phy_offset_array[i][0];
		if (ddrc_phy_offset_array[i][1] == READ_DATA_FROM_HARDWARE)
			p->ddrc_phy_val[i][1] =
				io_read32(p->ddrc_phy_va_base +
					  ddrc_phy_offset_array[i][0]);
		else
			p->ddrc_phy_val[i][1] = ddrc_phy_offset_array[i][1];
	}

	memcpy((void *)(suspend_ocram_base + sizeof(*p)),
	       (void *)(vaddr_t)imx7_suspend, SUSPEND_OCRAM_SIZE - sizeof(*p));

	dcache_clean_range((void *)suspend_ocram_base, SUSPEND_OCRAM_SIZE);

	/*
	 * Note that IRAM IOSEC map, if changed to MEM map,
	 * need to flush cache
	 */
	icache_inv_all();

	return 0;
}
