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

#include <common.h>
#include <binman_sym.h>
#include <log.h>
#include <spl.h>
#include <asm/global_data.h>
#include <asm/io.h>
#include <errno.h>
#include <asm/io.h>
#include <asm/arch/ddr.h>
#include <asm/arch/ddr.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)

binman_sym_declare(ulong, ddr_1d_imem_fw, image_pos);
binman_sym_declare(ulong, ddr_1d_imem_fw, size);

binman_sym_declare(ulong, ddr_1d_dmem_fw, image_pos);
binman_sym_declare(ulong, ddr_1d_dmem_fw, size);

#if !IS_ENABLED(CONFIG_IMX8M_DDR3L)
binman_sym_declare(ulong, ddr_2d_imem_fw, image_pos);
binman_sym_declare(ulong, ddr_2d_imem_fw, size);

binman_sym_declare(ulong, ddr_2d_dmem_fw, image_pos);
binman_sym_declare(ulong, ddr_2d_dmem_fw, size);
#endif

/* 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;
	uint32_t fw_offset = type ? IMEM_2D_OFFSET : 0;
	unsigned long imem_start = (unsigned long)_end + fw_offset;
	unsigned long dmem_start;
	unsigned long imem_len = IMEM_LEN, dmem_len = DMEM_LEN;

#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;

	if (BINMAN_SYMS_OK) {
		switch (type) {
		case FW_1D_IMAGE:
			imem_start = binman_sym(ulong, ddr_1d_imem_fw, image_pos);
			imem_len = binman_sym(ulong, ddr_1d_imem_fw, size);
			dmem_start = binman_sym(ulong, ddr_1d_dmem_fw, image_pos);
			dmem_len = binman_sym(ulong, ddr_1d_dmem_fw, size);
			break;
		case FW_2D_IMAGE:
#if !IS_ENABLED(CONFIG_IMX8M_DDR3L)
			imem_start = binman_sym(ulong, ddr_2d_imem_fw, image_pos);
			imem_len = binman_sym(ulong, ddr_2d_imem_fw, size);
			dmem_start = binman_sym(ulong, ddr_2d_dmem_fw, image_pos);
			dmem_len = binman_sym(ulong, ddr_2d_dmem_fw, size);
#endif
			break;
		}
	}

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

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

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

		if (tmp32 != readl(pr_from32)) {
			debug("%lx %lx\n", pr_from32, pr_to32);
			error++;
		}
		pr_from32 += 4;
		pr_to32 += 1;
		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 = DMEM_OFFSET_ADDR;
	for (i = 0x0; i < dmem_len;) {
		tmp32 = (readw(DDR_TRAIN_CODE_BASE_ADDR + ddrphy_addr_remap(pr_to32)) & 0x0000ffff);
		pr_to32 += 1;
		tmp32 += ((readw(DDR_TRAIN_CODE_BASE_ADDR +
			  ddrphy_addr_remap(pr_to32)) & 0x0000ffff) << 16);
		if (tmp32 != readl(pr_from32)) {
			debug("%lx %lx\n", pr_from32, pr_to32);
			error++;
		}
		pr_from32 += 4;
		pr_to32 += 1;
		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++;
	}

	return (void *)cfg;
}
