// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2017 NXP
 * Copyright 2020 Linaro
 *
 */

#include <common.h>
#include <spl.h>
#include <asm/io.h>
#include <errno.h>
#include <command.h>
#include <asm/io.h>
#include <asm/arch/lpddr4_define.h>
#include <asm/mach-imx/iomux-v3.h>
#include <asm/mach-imx/gpio.h>
#include <asm-generic/gpio.h>
#include <asm/arch/ddr.h>
#include <asm/arch/imx8mq_pins.h>
#include <asm/arch/sys_proto.h>
#include <asm/arch/clock.h>
#include <asm/mach-imx/gpio.h>
#include "ddr.h"

static unsigned int lpddr4_mr_read(unsigned int mr_rank, unsigned int mr_addr)
{
	unsigned int tmp;

	reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x1);
	do {
		tmp = reg32_read(DDRC_MRSTAT(0));
	} while (tmp & 0x1);

	reg32_write(DDRC_MRCTRL0(0), (mr_rank << 4) | 0x1);
	reg32_write(DDRC_MRCTRL1(0), (mr_addr << 8));
	reg32setbit(DDRC_MRCTRL0(0), 31);
	do {
		tmp = reg32_read(DRC_PERF_MON_MRR0_DAT(0));
	} while ((tmp & 0x8) == 0);
	tmp = reg32_read(DRC_PERF_MON_MRR1_DAT(0));
	reg32_write(DRC_PERF_MON_MRR0_DAT(0), 0x4);
	while (tmp) { //try to find a significant byte in the word
		if (tmp & 0xff) {
			tmp &= 0xff;
			break;
		}
		tmp >>= 8;
	}
	return tmp;
}

struct lpddr4_desc {
	char name[16];
	unsigned int id;
	unsigned int size;
	unsigned int count;
	/* an optional field
	 * use it if default is not the
	 * 1-st array entry
	 */
	unsigned int _default;
	/* An optional field to distiguish DRAM chips that
	 * have different geometry, though return the same MRR.
	 * Default value 0xff
	 */
	u8	subind;
	struct dram_timing_info *timing;
	char *desc[4];
};

#define DEFAULT (('D' << 24) + ('E' << 16) + ('F' << 8) + 'A')
static const struct lpddr4_desc lpddr4_array[] = {
	{ .name = "Nanya",	.id = 0x05000010, .subind = 0xff,
	  .size = 2048, .count = 1, .timing = &ucm_dram_timing_01061010},
	{ .name = "Samsung",	.id = 0x01061010, .subind = 0xff,
	  .size = 2048, .count = 1, .timing = &ucm_dram_timing_01061010},
	{ .name = "Kingston",	.id = 0xff000010, .subind = 0x04,
	  .size = 4096, .count = 1, .timing = &ucm_dram_timing_ff000110},
	{ .name = "Kingston",	.id = 0xff000010, .subind = 0x02,
	  .size = 2048, .count = 1, .timing = &ucm_dram_timing_01061010},
	{ .name = "Micron",	.id = 0xff020008, .subind = 0xff,
	  .size = 2048, .count = 1, .timing = &ucm_dram_timing_ff020008},
	{ .name = "Micron",	.id = 0xff000110, .subind = 0xff,
	  .size = 4096, .count = 1, .timing = &ucm_dram_timing_ff000110},
};

static unsigned int lpddr4_get_mr(void)
{
	int i = 0, attempts = 5;
	unsigned int ddr_info = 0;
	unsigned int regs[] = { 5, 6, 7, 8 };

	do {
		for (i = 0 ; i < ARRAY_SIZE(regs) ; i++) {
			unsigned int data = 0;

			data = lpddr4_mr_read(0xF, regs[i]);
			ddr_info <<= 8;
			ddr_info += (data & 0xFF);
		}
		if (ddr_info != 0xFFFFFFFF && ddr_info != 0)
			break; // The attempt was successful
	} while (--attempts);
	return	ddr_info;
}

static void spl_tcm_init(struct lpddr4_tcm_desc *lpddr4_tcm_desc)
{
	if (lpddr4_tcm_desc->sign == DEFAULT)
		return;

	lpddr4_tcm_desc->sign = DEFAULT;
	lpddr4_tcm_desc->index = 0;
}

static void spl_tcm_fini(struct lpddr4_tcm_desc *lpddr4_tcm_desc)
{
	if (lpddr4_tcm_desc->sign != DEFAULT)
		return;

	lpddr4_tcm_desc->sign = ~DEFAULT;
	lpddr4_tcm_desc->index = 0;
}

#define SPL_TCM_DATA 0x7e0000
#define SPL_TCM_INIT spl_tcm_init(lpddr4_tcm_desc)
#define SPL_TCM_FINI spl_tcm_fini(lpddr4_tcm_desc)

void spl_dram_init_compulab(void)
{
	unsigned int ddr_info = 0xdeadbeef;
	unsigned int ddr_info_mrr = 0xdeadbeef;
	unsigned int ddr_found = 0;
	int i = 0;

	struct lpddr4_tcm_desc *lpddr4_tcm_desc =
		(struct lpddr4_tcm_desc *)SPL_TCM_DATA;

	if (lpddr4_tcm_desc->sign != DEFAULT) {
		/* if not in tcm scan mode */
		for (i = 0; i < ARRAY_SIZE(lpddr4_array); i++) {
			if (lpddr4_array[i].id == ddr_info &&
			    lpddr4_array[i].subind == 0xff) {
				ddr_found = 1;
				break;
			}
		}
	}

	/* Walk trought all available ddr ids and apply
	 * one by one. Save the index at the tcm memory that
	 * persists after the reset.
	 */
	if (ddr_found == 0) {
		SPL_TCM_INIT;

		if (lpddr4_tcm_desc->index < ARRAY_SIZE(lpddr4_array)) {
			printf("DDRINFO: Cfg attempt: [ %d/%lu ]\n",
			       lpddr4_tcm_desc->index + 1,
			       ARRAY_SIZE(lpddr4_array));
			i = lpddr4_tcm_desc->index;
			lpddr4_tcm_desc->index += 1;
		} else {
			/* Ran out all available ddr setings */
			printf("DDRINFO: Ran out all [ %lu ] cfg attempts. A non supported configuration.\n",
			       ARRAY_SIZE(lpddr4_array));
			while (1)
				;
		}
		ddr_info = lpddr4_array[i].id;
	} else {
		printf("DDRINFO(%s): %s %dG\n", (ddr_found ? "D" : "?"),
		       lpddr4_array[i].name,
		       lpddr4_array[i].size);
	}

	if (ddr_init(lpddr4_array[i].timing)) {
		SPL_TCM_INIT;
		do_reset(NULL, 0, 0, NULL);
	}

	ddr_info_mrr = lpddr4_get_mr();
	if (ddr_info_mrr == 0xFFFFFFFF) {
		printf("DDRINFO(M): mr5-8 [ 0x%x ] is invalid; reset\n",
		       ddr_info_mrr);
		SPL_TCM_INIT;
		do_reset(NULL, 0, 0, NULL);
	}

	printf("DDRINFO(M): mr5-8 [ 0x%x ]\n", ddr_info_mrr);
	printf("DDRINFO(%s): mr5-8 [ 0x%x ]\n", (ddr_found ? "E" : "T"),
	       ddr_info);

	if (ddr_info_mrr != ddr_info) {
		SPL_TCM_INIT;
		do_reset(NULL, 0, 0, NULL);
	}

	SPL_TCM_FINI;

	/* Pass the dram size to th U-Boot through the tcm memory */
	{ /* To figure out what to store into the TCM buffer */
	  /* For debug purpouse only. To override the real memsize */
		unsigned int ddr_tcm_size = 0;

		if (ddr_tcm_size == 0 || ddr_tcm_size == -1)
			ddr_tcm_size = lpddr4_array[i].size;

		lpddr4_tcm_desc->size = ddr_tcm_size;
	}
}
