// SPDX-License-Identifier: GPL-2.0+
/*
 * Keystone : Board initialization
 *
 * (C) Copyright 2014
 *     Texas Instruments Incorporated, <www.ti.com>
 */

#include <common.h>
#include "board.h"
#include <env.h>
#include <hang.h>
#include <image.h>
#include <init.h>
#include <spl.h>
#include <exports.h>
#include <fdt_support.h>
#include <asm/arch/ddr3.h>
#include <asm/arch/psc_defs.h>
#include <asm/arch/clock.h>
#include <asm/ti-common/ti-aemif.h>
#include <asm/ti-common/keystone_net.h>

DECLARE_GLOBAL_DATA_PTR;

#if defined(CONFIG_TI_AEMIF)
static struct aemif_config aemif_configs[] = {
	{			/* CS0 */
		.mode		= AEMIF_MODE_NAND,
		.wr_setup	= 0xf,
		.wr_strobe	= 0x3f,
		.wr_hold	= 7,
		.rd_setup	= 0xf,
		.rd_strobe	= 0x3f,
		.rd_hold	= 7,
		.turn_around	= 3,
		.width		= AEMIF_WIDTH_8,
	},
};
#endif

int dram_init(void)
{
	u32 ddr3_size;

	ddr3_size = ddr3_init();

	gd->ram_size = get_ram_size((long *)CONFIG_SYS_SDRAM_BASE,
				    CONFIG_MAX_RAM_BANK_SIZE);
#if defined(CONFIG_TI_AEMIF)
	if (!(board_is_k2g_ice() || board_is_k2g_i1()))
		aemif_init(ARRAY_SIZE(aemif_configs), aemif_configs);
#endif

	if (!(board_is_k2g_ice() || board_is_k2g_i1())) {
		if (ddr3_size)
			ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE, ddr3_size);
		else
			ddr3_init_ecc(KS2_DDR3A_EMIF_CTRL_BASE,
				      gd->ram_size >> 30);
	}

	return 0;
}

struct image_header *spl_get_load_buffer(ssize_t offset, size_t size)
{
	return (struct image_header *)(CONFIG_SYS_TEXT_BASE);
}

int board_init(void)
{
	gd->bd->bi_boot_params = CONFIG_SYS_SDRAM_BASE + 0x100;
	return 0;
}

#ifdef CONFIG_SPL_BUILD
void spl_board_init(void)
{
	spl_init_keystone_plls();
	preloader_console_init();
}

u32 spl_boot_device(void)
{
#if defined(CONFIG_SPL_SPI_LOAD)
	return BOOT_DEVICE_SPI;
#else
	puts("Unknown boot device\n");
	hang();
#endif
}
#endif

#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, struct bd_info *bd)
{
	int lpae;
	char *env;
	char *endp;
	int nbanks;
	u64 size[2];
	u64 start[2];
	u32 ddr3a_size;

	env = env_get("mem_lpae");
	lpae = env && simple_strtol(env, NULL, 0);

	ddr3a_size = 0;
	if (lpae) {
		ddr3a_size = ddr3_get_size();
		if ((ddr3a_size != 8) && (ddr3a_size != 4))
			ddr3a_size = 0;
	}

	nbanks = 1;
	start[0] = bd->bi_dram[0].start;
	size[0]  = bd->bi_dram[0].size;

	/* adjust memory start address for LPAE */
	if (lpae) {
		start[0] -= CONFIG_SYS_SDRAM_BASE;
		start[0] += CONFIG_SYS_LPAE_SDRAM_BASE;
	}

	if ((size[0] == 0x80000000) && (ddr3a_size != 0)) {
		size[1] = ((u64)ddr3a_size - 2) << 30;
		start[1] = 0x880000000;
		nbanks++;
	}

	/* reserve memory at start of bank */
	env = env_get("mem_reserve_head");
	if (env) {
		start[0] += ustrtoul(env, &endp, 0);
		size[0] -= ustrtoul(env, &endp, 0);
	}

	env = env_get("mem_reserve");
	if (env)
		size[0] -= ustrtoul(env, &endp, 0);

	fdt_fixup_memory_banks(blob, start, size, nbanks);

	return 0;
}

void ft_board_setup_ex(void *blob, struct bd_info *bd)
{
	int lpae;
	u64 size;
	char *env;
	u64 *reserve_start;
	int unitrd_fixup = 0;

	env = env_get("mem_lpae");
	lpae = env && simple_strtol(env, NULL, 0);
	env = env_get("uinitrd_fixup");
	unitrd_fixup = env && simple_strtol(env, NULL, 0);

	/* Fix up the initrd */
	if (lpae && unitrd_fixup) {
		int nodeoffset;
		int err;
		u64 *prop1, *prop2;
		u64 initrd_start, initrd_end;

		nodeoffset = fdt_path_offset(blob, "/chosen");
		if (nodeoffset >= 0) {
			prop1 = (u64 *)fdt_getprop(blob, nodeoffset,
					    "linux,initrd-start", NULL);
			prop2 = (u64 *)fdt_getprop(blob, nodeoffset,
					    "linux,initrd-end", NULL);
			if (prop1 && prop2) {
				initrd_start = __be64_to_cpu(*prop1);
				initrd_start -= CONFIG_SYS_SDRAM_BASE;
				initrd_start += CONFIG_SYS_LPAE_SDRAM_BASE;
				initrd_start = __cpu_to_be64(initrd_start);
				initrd_end = __be64_to_cpu(*prop2);
				initrd_end -= CONFIG_SYS_SDRAM_BASE;
				initrd_end += CONFIG_SYS_LPAE_SDRAM_BASE;
				initrd_end = __cpu_to_be64(initrd_end);

				err = fdt_delprop(blob, nodeoffset,
						  "linux,initrd-start");
				if (err < 0)
					puts("error deleting initrd-start\n");

				err = fdt_delprop(blob, nodeoffset,
						  "linux,initrd-end");
				if (err < 0)
					puts("error deleting initrd-end\n");

				err = fdt_setprop(blob, nodeoffset,
						  "linux,initrd-start",
						  &initrd_start,
						  sizeof(initrd_start));
				if (err < 0)
					puts("error adding initrd-start\n");

				err = fdt_setprop(blob, nodeoffset,
						  "linux,initrd-end",
						  &initrd_end,
						  sizeof(initrd_end));
				if (err < 0)
					puts("error adding linux,initrd-end\n");
			}
		}
	}

	if (lpae) {
		/*
		 * the initrd and other reserved memory areas are
		 * embedded in in the DTB itslef. fix up these addresses
		 * to 36 bit format
		 */
		reserve_start = (u64 *)((char *)blob +
				       fdt_off_mem_rsvmap(blob));
		while (1) {
			*reserve_start = __cpu_to_be64(*reserve_start);
			size = __cpu_to_be64(*(reserve_start + 1));
			if (size) {
				*reserve_start -= CONFIG_SYS_SDRAM_BASE;
				*reserve_start +=
					CONFIG_SYS_LPAE_SDRAM_BASE;
				*reserve_start =
					__cpu_to_be64(*reserve_start);
			} else {
				break;
			}
			reserve_start += 2;
		}
	}

	ddr3_check_ecc_int(KS2_DDR3A_EMIF_CTRL_BASE);
}
#endif /* CONFIG_OF_BOARD_SETUP */

#if defined(CONFIG_DTB_RESELECT)
int __weak embedded_dtb_select(void)
{
	return 0;
}
#endif
