// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (c) 2016 Google, Inc
 *
 * From coreboot src/soc/intel/broadwell/romstage/raminit.c
 */

#include <common.h>
#include <dm.h>
#include <init.h>
#include <log.h>
#include <pci.h>
#include <syscon.h>
#include <asm/cpu.h>
#include <asm/io.h>
#include <asm/lpc_common.h>
#include <asm/mrccache.h>
#include <asm/mrc_common.h>
#include <asm/mtrr.h>
#include <asm/pci.h>
#include <asm/arch/iomap.h>
#include <asm/arch/me.h>
#include <asm/arch/pch.h>
#include <asm/arch/pei_data.h>
#include <asm/arch/pm.h>

ulong board_get_usable_ram_top(ulong total_size)
{
	return mrc_common_board_get_usable_ram_top(total_size);
}

int dram_init_banksize(void)
{
	mrc_common_dram_init_banksize();

	return 0;
}

static unsigned long get_top_of_ram(struct udevice *dev)
{
	/*
	 * Base of DPR is top of usable DRAM below 4GiB. The register has
	 * 1 MiB alignment and reports the TOP of the range, the base
	 * must be calculated from the size in MiB in bits 11:4.
	 */
	u32 dpr, tom;

	dm_pci_read_config32(dev, DPR, &dpr);
	tom = dpr & ~((1 << 20) - 1);

	debug("dpt %08x tom %08x\n", dpr, tom);
	/* Subtract DMA Protected Range size if enabled */
	if (dpr & DPR_EPM)
		tom -= (dpr & DPR_SIZE_MASK) << 16;

	return (unsigned long)tom;
}

/**
 * sdram_find() - Find available memory
 *
 * This is a bit complicated since on x86 there are system memory holes all
 * over the place. We create a list of available memory blocks
 *
 * @dev:	Northbridge device
 */
static int sdram_find(struct udevice *dev)
{
	struct memory_info *info = &gd->arch.meminfo;
	ulong top_of_ram;

	top_of_ram = get_top_of_ram(dev);
	mrc_add_memory_area(info, 0, top_of_ram);

	/* Add MTRRs for memory */
	mtrr_add_request(MTRR_TYPE_WRBACK, 0, 2ULL << 30);

	return 0;
}

static int prepare_mrc_cache(struct pei_data *pei_data)
{
	struct mrc_data_container *mrc_cache;
	struct mrc_region entry;
	int ret;

	ret = mrccache_get_region(MRC_TYPE_NORMAL, NULL, &entry);
	if (ret)
		return ret;
	mrc_cache = mrccache_find_current(&entry);
	if (!mrc_cache)
		return -ENOENT;

	pei_data->saved_data = mrc_cache->data;
	pei_data->saved_data_size = mrc_cache->data_size;
	debug("%s: at %p, size %x checksum %04x\n", __func__,
	      pei_data->saved_data, pei_data->saved_data_size,
	      mrc_cache->checksum);

	return 0;
}

int dram_init(void)
{
	struct pei_data _pei_data __aligned(8);
	struct pei_data *pei_data = &_pei_data;
	struct udevice *dev, *me_dev, *pch_dev;
	struct chipset_power_state ps;
	const void *spd_data;
	int ret, size;

	memset(pei_data, '\0', sizeof(struct pei_data));

	/* Print ME state before MRC */
	ret = syscon_get_by_driver_data(X86_SYSCON_ME, &me_dev);
	if (ret) {
		debug("Cannot get ME (err=%d)\n", ret);
		return ret;
	}
	intel_me_status(me_dev);

	/* Save ME HSIO version */
	ret = uclass_first_device_err(UCLASS_PCH, &pch_dev);
	if (ret) {
		debug("Cannot get PCH (err=%d)\n", ret);
		return ret;
	}
	power_state_get(pch_dev, &ps);

	intel_me_hsio_version(me_dev, &ps.hsio_version, &ps.hsio_checksum);

	broadwell_fill_pei_data(pei_data);
	mainboard_fill_pei_data(pei_data);

	ret = uclass_first_device_err(UCLASS_NORTHBRIDGE, &dev);
	if (ret) {
		debug("Cannot get Northbridge (err=%d)\n", ret);
		return ret;
	}
	size = 256;
	ret = mrc_locate_spd(dev, size, &spd_data);
	if (ret) {
		debug("Cannot locate SPD (err=%d)\n", ret);
		return ret;
	}
	memcpy(pei_data->spd_data[0][0], spd_data, size);
	memcpy(pei_data->spd_data[1][0], spd_data, size);

	ret = prepare_mrc_cache(pei_data);
	if (ret)
		debug("prepare_mrc_cache failed: %d\n", ret);

	debug("PEI version %#x\n", pei_data->pei_version);
	ret = mrc_common_init(dev, pei_data, true);
	if (ret) {
		debug("mrc_common_init() failed(err=%d)\n", ret);
		return ret;
	}
	debug("Memory init done\n");

	ret = sdram_find(dev);
	if (ret) {
		debug("sdram_find() failed (err=%d)\n", ret);
		return ret;
	}
	gd->ram_size = gd->arch.meminfo.total_32bit_memory;
	debug("RAM size %llx\n", (unsigned long long)gd->ram_size);

	debug("MRC output data length %#x at %p\n", pei_data->data_to_save_size,
	      pei_data->data_to_save);
	/* S3 resume: don't save scrambler seed or MRC data */
	if (pei_data->boot_mode != SLEEP_STATE_S3) {
		struct mrc_output *mrc = &gd->arch.mrc[MRC_TYPE_NORMAL];

		/*
		 * This will be copied to SDRAM in reserve_arch(), then written
		 * to SPI flash in mrccache_save()
		 */
		mrc->buf = (char *)pei_data->data_to_save;
		mrc->len = pei_data->data_to_save_size;
	}
	gd->arch.pei_meminfo = pei_data->meminfo;

	return 0;
}

/* Use this hook to save our SDRAM parameters */
int misc_init_r(void)
{
	int ret;

	ret = mrccache_save();
	if (ret)
		printf("Unable to save MRC data: %d\n", ret);
	else
		debug("Saved MRC cache data\n");

	return 0;
}

static const struct udevice_id broadwell_syscon_ids[] = {
	{ .compatible = "intel,me", .data = X86_SYSCON_ME },
	{ }
};

U_BOOT_DRIVER(syscon_intel_me) = {
	.name = "intel_me_syscon",
	.id = UCLASS_SYSCON,
	.of_match = broadwell_syscon_ids,
};
