/*
 * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved.
 * Copyright (c) 2015-2017, Renesas Electronics Corporation. All rights reserved.
 *
 * Redistribution and use in source and binary forms, with or without
 * modification, are permitted provided that the following conditions are met:
 *
 * Redistributions of source code must retain the above copyright notice, this
 * list of conditions and the following disclaimer.
 *
 * Redistributions in binary form must reproduce the above copyright notice,
 * this list of conditions and the following disclaimer in the documentation
 * and/or other materials provided with the distribution.
 *
 * Neither the name of ARM nor the names of its contributors may be used
 * to endorse or promote products derived from this software without specific
 * prior written permission.
 *
 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
 * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
 * POSSIBILITY OF SUCH DAMAGE.
 */

#include <arch.h>
#include <arch_helpers.h>
#include <arm_gic.h>
#include <assert.h>
#include <bl_common.h>
#include <bl31.h>
#include <console.h>
#include <mmio.h>
#include <platform.h>
#include <stddef.h>
#include <debug.h>
#include "drivers/pwrc/rcar_pwrc.h"
#include "rcar_def.h"
#include "rcar_private.h"
#include "rcar_version.h"


/* Product Register */
#define PRR                     (0xFFF00044U)
#define PRR_PRODUCT_MASK        (0x00007F00U)
#define PRR_CUT_MASK            (0x000000FFU)
#define PRR_MAJOR_MASK          (0x000000F0U)
#define PRR_MINOR_MASK          (0x0000000FU)
#define PRR_PRODUCT_SHIFT       (8U)
#define PRR_MAJOR_SHIFT         (4U)
#define PRR_MINOR_SHIFT         (0U)
#define PRR_MAJOR_OFFSET        (1U)
#define PRR_PRODUCT_H3          (0x00004F00U)           /* R-Car H3 */
#define PRR_PRODUCT_M3          (0x00005200U)           /* R-Car M3 */
#define PRR_PRODUCT_H3_ES_1_0   (0x00004F00U)           /* R-Car H3 ES1.0 */
#define PRR_PRODUCT_V3M         (0x00005400U)           /* R-Car V3M */

/* MIDR */
#define MIDR_CA57		(0x0D07U << MIDR_PN_SHIFT)
#define MIDR_CA53		(0x0D03U << MIDR_PN_SHIFT)


/* Array of secure interrupts to be configured by the gic driver */
//const unsigned int irq_sec_array[] = {
//	ARM_IRQ_SEC_PHY_TIMER,		/* 29		*/
//	ARM_IRQ_SEC_SGI_0,		/* 8		*/
//	ARM_IRQ_SEC_SGI_1,		/* 9		*/
//	ARM_IRQ_SEC_SGI_2,		/* 10		*/
//	ARM_IRQ_SEC_SGI_3,		/* 11		*/
//	ARM_IRQ_SEC_SGI_4,		/* 12		*/
//	ARM_IRQ_SEC_SGI_5,		/* 13		*/
//	ARM_IRQ_SEC_SGI_6,		/* 14		*/
//	ARM_IRQ_SEC_SGI_7,		/* 15		*/
//	ARM_IRQ_SEC_RPC,		/* 70		*/
//	ARM_IRQ_SEC_TIMER,		/* 166		*/
//	ARM_IRQ_SEC_TIMER_UP,		/* 171		*/
//	ARM_IRQ_SEC_WDT,		/* 173		*/
//	ARM_IRQ_SEC_CRYPT,		/* 102		*/
//	ARM_IRQ_SEC_CRYPT_SecPKA,	/* 97		*/
//	ARM_IRQ_SEC_CRYPT_PubPKA,	/* 98		*/
//	ARM_IRQ_SEC_DMAC2_ERR,		/* 448		*/
//	ARM_IRQ_SEC_DMAC2_0,		/* 449		*/
//	ARM_IRQ_SEC_DMAC2_1,		/* 450		*/
//	ARM_IRQ_SEC_DMAC2_2,		/* 451		*/
//	ARM_IRQ_SEC_DMAC2_3,		/* 452		*/
//	ARM_IRQ_SEC_DMAC2_4,		/* 453		*/
//	ARM_IRQ_SEC_DMAC2_5,		/* 454		*/
//	ARM_IRQ_SEC_DMAC2_6,		/* 455		*/
//	ARM_IRQ_SEC_DMAC2_7,		/* 456		*/
//	ARM_IRQ_SEC_DMAC2_8,		/* 457		*/
//	ARM_IRQ_SEC_DMAC2_9,		/* 458		*/
//	ARM_IRQ_SEC_DMAC2_10,		/* 459		*/
//	ARM_IRQ_SEC_DMAC2_11,		/* 460		*/
//	ARM_IRQ_SEC_DMAC2_12,		/* 461		*/
//	ARM_IRQ_SEC_DMAC2_13,		/* 462		*/
//	ARM_IRQ_SEC_DMAC2_14,		/* 463		*/
//	ARM_IRQ_SEC_DMAC2_15		/* 429		*/
//};

/*******************************************************************************
 * Perform any BL31 specific platform actions. Here is an opportunity to copy
 * parameters passed by the calling EL (S-EL1 in BL2) before they
 * are lost (potentially). This needs to be done before the MMU is initialized
 * so that the memory layout can be used while creating page tables. On the RCAR
 * we know that BL2 has populated the parameters. So we just use
 * the reference passed in 'from_bl2' instead of copying. The 'data' parameter
 * is not used since all the information is contained in 'from_bl2'. Also, BL2
 * has flushed this information to memory, so we are guaranteed to pick up good
 * data
 ******************************************************************************/
void bl33_early_platform_setup(void)
{
	uint32_t reg;
	const char *str;
	const char *cpu_ca57        = "CA57";
	const char *cpu_ca53        = "CA53";
	const char *product_h3      = "H3";
	const char *product_m3      = "M3";
	const char *product_v3m     = "V3M";
	const char *unknown         = "unknown";

	/* Initialize the log area to provide early debug support */
	console_init(1U, 0U, 0U);

	/* boot message */
	reg = (uint32_t)read_midr();
	switch (reg & (MIDR_PN_MASK << MIDR_PN_SHIFT)) { 
	case MIDR_CA57:
		str = cpu_ca57;
		break;
	case MIDR_CA53:
		str = cpu_ca53;
		break;
	default:
		str = unknown;
	}
	NOTICE("BL3-3: R-Car H3/M3/V3M Dummy BL33(%s) Rev.%s\n", 
					str, version_of_renesas);

	/* product version */
	reg = mmio_read_32(PRR);
	switch (reg & PRR_PRODUCT_MASK) {
	case PRR_PRODUCT_H3:
		str = product_h3;
		break;
	case PRR_PRODUCT_M3:
		str = product_m3;
		break;
	case PRR_PRODUCT_V3M:
		str = product_v3m;
		break;
	default:
		str = unknown;
	}
	NOTICE("BL3-3: PRR is R-Car %s Ver%d.%d\n", str,
		((reg & PRR_MAJOR_MASK) >> PRR_MAJOR_SHIFT) + PRR_MAJOR_OFFSET,
		 (reg & PRR_MINOR_MASK) >> PRR_MINOR_SHIFT);
}

/*******************************************************************************
 * Initialize the gic, configure the CLCD and zero out variables needed by the
 * secondaries to boot up correctly.
 ******************************************************************************/
void bl33_platform_setup(void)
{

	/* Initialize the gic cpu and distributor interfaces */
//	arm_gic_init(RCAR_GICC_BASE, RCAR_GICD_BASE, RCAR_GICR_BASE,
//			irq_sec_array, ARRAY_SIZE(irq_sec_array));
//	arm_gic_setup();

	/* Enable and initialize the System level generic timer */
//	mmio_write_32(RCAR_CNTC_BASE + CNTCR_OFF, CNTCR_FCREQ(0) | CNTCR_EN);

	/* Intialize the power controller */
//	rcar_pwrc_setup();

	/* Topologies are best known to the platform. */
//	rcar_setup_topology();
}

/*******************************************************************************
 * Perform the very early platform specific architectural setup here. At the
 * moment this is only intializes the mmu in a quick and dirty way.
 ******************************************************************************/
void bl33_plat_arch_setup(void)
{
//	rcar_configure_mmu_el3(BL31_RO_BASE, (BL31_END - BL31_RO_BASE),
//			BL31_RO_BASE,
//			BL31_RO_LIMIT
//#if USE_COHERENT_MEM
//			, BL31_COHERENT_RAM_BASE,
//			BL31_COHERENT_RAM_LIMIT
//#endif
//	);

}
