// SPDX-License-Identifier: GPL-2.0+
/*
 * Copyright 2018 NXP
 */

#include <common.h>
#include <log.h>
#include <spl.h>
#include <asm/io.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/arch/ddr.h>
#include <asm/arch/ddr.h>
#include <asm/arch/lpddr4_define.h>
#include <asm/sections.h>

DECLARE_GLOBAL_DATA_PTR;

#define IMEM_LEN 32768 /* byte */
#define DMEM_LEN 16384 /* byte */
#define IMEM_2D_OFFSET	49152

#define IMEM_OFFSET_ADDR 0x00050000
#define DMEM_OFFSET_ADDR 0x00054000
#define DDR_TRAIN_CODE_BASE_ADDR IP2APB_DDRPHY_IPS_BASE_ADDR(0)

/* We need PHY iMEM PHY is 32KB padded */
void ddr_load_train_firmware(enum fw_type type)
{
	u32 tmp32, i;
	u32 error = 0;
	unsigned long pr_to32, pr_from32;
	unsigned long fw_offset = type ? IMEM_2D_OFFSET : 0;
	unsigned long imem_start = (unsigned long)&_end + fw_offset;
	unsigned long dmem_start;

#ifdef CONFIG_SPL_OF_CONTROL
	if (gd->fdt_blob && !fdt_check_header(gd->fdt_blob)) {
		imem_start = roundup((unsigned long)&_end +
				     fdt_totalsize(gd->fdt_blob), 4) +
			fw_offset;
	}
#endif

	dmem_start = imem_start + IMEM_LEN;

	pr_from32 = imem_start;
	pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * IMEM_OFFSET_ADDR;
	for (i = 0x0; i < IMEM_LEN; ) {
		tmp32 = readl(pr_from32);
		writew(tmp32 & 0x0000ffff, pr_to32);
		pr_to32 += 4;
		writew((tmp32 >> 16) & 0x0000ffff, pr_to32);
		pr_to32 += 4;
		pr_from32 += 4;
		i += 4;
	}

	pr_from32 = dmem_start;
	pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * DMEM_OFFSET_ADDR;
	for (i = 0x0; i < DMEM_LEN; ) {
		tmp32 = readl(pr_from32);
		writew(tmp32 & 0x0000ffff, pr_to32);
		pr_to32 += 4;
		writew((tmp32 >> 16) & 0x0000ffff, pr_to32);
		pr_to32 += 4;
		pr_from32 += 4;
		i += 4;
	}

	debug("check ddr_pmu_train_imem code\n");
	pr_from32 = imem_start;
	pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * IMEM_OFFSET_ADDR;
	for (i = 0x0; i < IMEM_LEN; ) {
		tmp32 = (readw(pr_to32) & 0x0000ffff);
		pr_to32 += 4;
		tmp32 += ((readw(pr_to32) & 0x0000ffff) << 16);

		if (tmp32 != readl(pr_from32)) {
			debug("%lx %lx\n", pr_from32, pr_to32);
			error++;
		}
		pr_from32 += 4;
		pr_to32 += 4;
		i += 4;
	}
	if (error)
		printf("check ddr_pmu_train_imem code fail=%d\n", error);
	else
		debug("check ddr_pmu_train_imem code pass\n");

	debug("check ddr4_pmu_train_dmem code\n");
	pr_from32 = dmem_start;
	pr_to32 = DDR_TRAIN_CODE_BASE_ADDR + 4 * DMEM_OFFSET_ADDR;
	for (i = 0x0; i < DMEM_LEN;) {
		tmp32 = (readw(pr_to32) & 0x0000ffff);
		pr_to32 += 4;
		tmp32 += ((readw(pr_to32) & 0x0000ffff) << 16);
		if (tmp32 != readl(pr_from32)) {
			debug("%lx %lx\n", pr_from32, pr_to32);
			error++;
		}
		pr_from32 += 4;
		pr_to32 += 4;
		i += 4;
	}

	if (error)
		printf("check ddr_pmu_train_dmem code fail=%d", error);
	else
		debug("check ddr_pmu_train_dmem code pass\n");
}

void ddrphy_trained_csr_save(struct dram_cfg_param *ddrphy_csr,
			     unsigned int num)
{
	int i = 0;

	/* enable the ddrphy apb */
	dwc_ddrphy_apb_wr(0xd0000, 0x0);
	dwc_ddrphy_apb_wr(0xc0080, 0x3);
	for (i = 0; i < num; i++) {
		ddrphy_csr->val = dwc_ddrphy_apb_rd(ddrphy_csr->reg);
		ddrphy_csr++;
	}
	/* disable the ddrphy apb */
	dwc_ddrphy_apb_wr(0xc0080, 0x2);
	dwc_ddrphy_apb_wr(0xd0000, 0x1);
}

void dram_config_save(struct dram_timing_info *timing_info,
		      unsigned long saved_timing_base)
{
	int i = 0;
	struct dram_timing_info *saved_timing = (struct dram_timing_info *)saved_timing_base;
	struct dram_cfg_param *cfg;

	saved_timing->ddrc_cfg_num = timing_info->ddrc_cfg_num;
	saved_timing->ddrphy_cfg_num = timing_info->ddrphy_cfg_num;
	saved_timing->ddrphy_trained_csr_num = ddrphy_trained_csr_num;
	saved_timing->ddrphy_pie_num = timing_info->ddrphy_pie_num;

	/* save the fsp table */
	for (i = 0; i < 4; i++)
		saved_timing->fsp_table[i] = timing_info->fsp_table[i];

	cfg = (struct dram_cfg_param *)(saved_timing_base +
					sizeof(*timing_info));

	/* save ddrc config */
	saved_timing->ddrc_cfg = cfg;
	for (i = 0; i < timing_info->ddrc_cfg_num; i++) {
		cfg->reg = timing_info->ddrc_cfg[i].reg;
		cfg->val = timing_info->ddrc_cfg[i].val;
		cfg++;
	}

	/* save ddrphy config */
	saved_timing->ddrphy_cfg = cfg;
	for (i = 0; i < timing_info->ddrphy_cfg_num; i++) {
		cfg->reg = timing_info->ddrphy_cfg[i].reg;
		cfg->val = timing_info->ddrphy_cfg[i].val;
		cfg++;
	}

	/* save the ddrphy csr */
	saved_timing->ddrphy_trained_csr = cfg;
	for (i = 0; i < ddrphy_trained_csr_num; i++) {
		cfg->reg = ddrphy_trained_csr[i].reg;
		cfg->val = ddrphy_trained_csr[i].val;
		cfg++;
	}

	/* save the ddrphy pie */
	saved_timing->ddrphy_pie = cfg;
	for (i = 0; i < timing_info->ddrphy_pie_num; i++) {
		cfg->reg = timing_info->ddrphy_pie[i].reg;
		cfg->val = timing_info->ddrphy_pie[i].val;
		cfg++;
	}
}
