// SPDX-License-Identifier: GPL-2.0
/*
 * Copyright (C) 2016-2018 Intel Corporation <www.intel.com>
 *
 */

#include <common.h>
#include <cpu_func.h>
#include <dm.h>
#include <errno.h>
#include <div64.h>
#include <fdtdec.h>
#include <hang.h>
#include <init.h>
#include <log.h>
#include <ram.h>
#include <reset.h>
#include "sdram_s10.h"
#include <wait_bit.h>
#include <asm/arch/firewall.h>
#include <asm/arch/reset_manager.h>
#include <asm/io.h>
#include <linux/sizes.h>

DECLARE_GLOBAL_DATA_PTR;

#define DDR_CONFIG(A, B, C, R)	(((A) << 24) | ((B) << 16) | ((C) << 8) | (R))

/* The followring are the supported configurations */
u32 ddr_config[] = {
	/* DDR_CONFIG(Address order,Bank,Column,Row) */
	/* List for DDR3 or LPDDR3 (pinout order > chip, row, bank, column) */
	DDR_CONFIG(0, 3, 10, 12),
	DDR_CONFIG(0, 3,  9, 13),
	DDR_CONFIG(0, 3, 10, 13),
	DDR_CONFIG(0, 3,  9, 14),
	DDR_CONFIG(0, 3, 10, 14),
	DDR_CONFIG(0, 3, 10, 15),
	DDR_CONFIG(0, 3, 11, 14),
	DDR_CONFIG(0, 3, 11, 15),
	DDR_CONFIG(0, 3, 10, 16),
	DDR_CONFIG(0, 3, 11, 16),
	DDR_CONFIG(0, 3, 12, 15),	/* 0xa */
	/* List for DDR4 only (pinout order > chip, bank, row, column) */
	DDR_CONFIG(1, 3, 10, 14),
	DDR_CONFIG(1, 4, 10, 14),
	DDR_CONFIG(1, 3, 10, 15),
	DDR_CONFIG(1, 4, 10, 15),
	DDR_CONFIG(1, 3, 10, 16),
	DDR_CONFIG(1, 4, 10, 16),
	DDR_CONFIG(1, 3, 10, 17),
	DDR_CONFIG(1, 4, 10, 17),
};

int match_ddr_conf(u32 ddr_conf)
{
	int i;

	for (i = 0; i < ARRAY_SIZE(ddr_config); i++) {
		if (ddr_conf == ddr_config[i])
			return i;
	}
	return 0;
}

/**
 * sdram_mmr_init_full() - Function to initialize SDRAM MMR
 *
 * Initialize the SDRAM MMR.
 */
int sdram_mmr_init_full(struct udevice *dev)
{
	struct altera_sdram_platdata *plat = dev->platdata;
	struct altera_sdram_priv *priv = dev_get_priv(dev);
	u32 update_value, io48_value, ddrioctl;
	u32 i;
	int ret;
	phys_size_t hw_size;
	bd_t bd = {0};

	/* Enable access to DDR from CPU master */
	clrbits_le32(CCU_REG_ADDR(CCU_CPU0_MPRT_ADBASE_DDRREG),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_CPU0_MPRT_ADBASE_MEMSPACE0),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_CPU0_MPRT_ADBASE_MEMSPACE1A),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_CPU0_MPRT_ADBASE_MEMSPACE1B),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_CPU0_MPRT_ADBASE_MEMSPACE1C),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_CPU0_MPRT_ADBASE_MEMSPACE1D),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_CPU0_MPRT_ADBASE_MEMSPACE1E),
		     CCU_ADBASE_DI_MASK);

	/* Enable access to DDR from IO master */
	clrbits_le32(CCU_REG_ADDR(CCU_IOM_MPRT_ADBASE_MEMSPACE0),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_IOM_MPRT_ADBASE_MEMSPACE1A),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_IOM_MPRT_ADBASE_MEMSPACE1B),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_IOM_MPRT_ADBASE_MEMSPACE1C),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_IOM_MPRT_ADBASE_MEMSPACE1D),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_IOM_MPRT_ADBASE_MEMSPACE1E),
		     CCU_ADBASE_DI_MASK);

	/* Enable access to DDR from TCU */
	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE0),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE1A),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE1B),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE1C),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE1D),
		     CCU_ADBASE_DI_MASK);
	clrbits_le32(CCU_REG_ADDR(CCU_TCU_MPRT_ADBASE_MEMSPACE1E),
		     CCU_ADBASE_DI_MASK);

	/* this enables nonsecure access to DDR */
	/* mpuregion0addr_limit */
	FW_MPU_DDR_SCR_WRITEL(0xFFFF0000, FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMIT);
	FW_MPU_DDR_SCR_WRITEL(0x1F, FW_MPU_DDR_SCR_MPUREGION0ADDR_LIMITEXT);

	/* nonmpuregion0addr_limit */
	FW_MPU_DDR_SCR_WRITEL(0xFFFF0000,
			      FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMIT);
	FW_MPU_DDR_SCR_WRITEL(0x1F, FW_MPU_DDR_SCR_NONMPUREGION0ADDR_LIMITEXT);

	/* Enable mpuregion0enable and nonmpuregion0enable */
	FW_MPU_DDR_SCR_WRITEL(MPUREGION0_ENABLE | NONMPUREGION0_ENABLE,
			      FW_MPU_DDR_SCR_EN_SET);

	/* Ensure HMC clock is running */
	if (poll_hmc_clock_status()) {
		puts("DDR: Error as HMC clock not running\n");
		return -1;
	}

	/* Try 3 times to do a calibration */
	for (i = 0; i < 3; i++) {
		ret = wait_for_bit_le32((const void *)(plat->hmc +
					DDRCALSTAT),
					DDR_HMC_DDRCALSTAT_CAL_MSK, true, 1000,
					false);
		if (!ret)
			break;

		emif_reset(plat);
	}

	if (ret) {
		puts("DDR: Error as SDRAM calibration failed\n");
		return -1;
	}
	debug("DDR: Calibration success\n");

	u32 ctrlcfg0 = hmc_readl(plat, CTRLCFG0);
	u32 ctrlcfg1 = hmc_readl(plat, CTRLCFG1);
	u32 dramaddrw = hmc_readl(plat, DRAMADDRW);
	u32 dramtim0 = hmc_readl(plat, DRAMTIMING0);
	u32 caltim0 = hmc_readl(plat, CALTIMING0);
	u32 caltim1 = hmc_readl(plat, CALTIMING1);
	u32 caltim2 = hmc_readl(plat, CALTIMING2);
	u32 caltim3 = hmc_readl(plat, CALTIMING3);
	u32 caltim4 = hmc_readl(plat, CALTIMING4);
	u32 caltim9 = hmc_readl(plat, CALTIMING9);

	/*
	 * Configure the DDR IO size [0xFFCFB008]
	 * niosreserve0: Used to indicate DDR width &
	 *	bit[7:0] = Number of data bits (bit[6:5] 0x01=32bit, 0x10=64bit)
	 *	bit[8]   = 1 if user-mode OCT is present
	 *	bit[9]   = 1 if warm reset compiled into EMIF Cal Code
	 *	bit[10]  = 1 if warm reset is on during generation in EMIF Cal
	 * niosreserve1: IP ADCDS version encoded as 16 bit value
	 *	bit[2:0] = Variant (0=not special,1=FAE beta, 2=Customer beta,
	 *			    3=EAP, 4-6 are reserved)
	 *	bit[5:3] = Service Pack # (e.g. 1)
	 *	bit[9:6] = Minor Release #
	 *	bit[14:10] = Major Release #
	 */
	update_value = hmc_readl(plat, NIOSRESERVED0);
	hmc_ecc_writel(plat, ((update_value & 0xFF) >> 5), DDRIOCTRL);
	ddrioctl = hmc_ecc_readl(plat, DDRIOCTRL);

	/* enable HPS interface to HMC */
	hmc_ecc_writel(plat, DDR_HMC_HPSINTFCSEL_ENABLE_MASK, HPSINTFCSEL);

	/* Set the DDR Configuration */
	io48_value = DDR_CONFIG(CTRLCFG1_CFG_ADDR_ORDER(ctrlcfg1),
				(DRAMADDRW_CFG_BANK_ADDR_WIDTH(dramaddrw) +
				 DRAMADDRW_CFG_BANK_GRP_ADDR_WIDTH(dramaddrw)),
				DRAMADDRW_CFG_COL_ADDR_WIDTH(dramaddrw),
				DRAMADDRW_CFG_ROW_ADDR_WIDTH(dramaddrw));

	update_value = match_ddr_conf(io48_value);
	if (update_value)
		ddr_sch_writel(plat, update_value, DDR_SCH_DDRCONF);

	/* Configure HMC dramaddrw */
	hmc_ecc_writel(plat, hmc_readl(plat, DRAMADDRW), DRAMADDRWIDTH);

	/*
	 * Configure DDR timing
	 *  RDTOMISS = tRTP + tRP + tRCD - BL/2
	 *  WRTOMISS = WL + tWR + tRP + tRCD and
	 *    WL = RL + BL/2 + 2 - rd-to-wr ; tWR = 15ns  so...
	 *  First part of equation is in memory clock units so divide by 2
	 *  for HMC clock units. 1066MHz is close to 1ns so use 15 directly.
	 *  WRTOMISS = ((RL + BL/2 + 2 + tWR) >> 1)- rd-to-wr + tRP + tRCD
	 */
	u32 burst_len = CTRLCFG0_CFG_CTRL_BURST_LEN(ctrlcfg0);

	update_value = CALTIMING2_CFG_RD_TO_WR_PCH(caltim2) +
		       CALTIMING4_CFG_PCH_TO_VALID(caltim4) +
		       CALTIMING0_CFG_ACT_TO_RDWR(caltim0) -
		       (burst_len >> 2);
	io48_value = (((DRAMTIMING0_CFG_TCL(dramtim0) + 2 + DDR_TWR +
		       (burst_len >> 1)) >> 1) -
		      /* Up to here was in memory cycles so divide by 2 */
		      CALTIMING1_CFG_RD_TO_WR(caltim1) +
		      CALTIMING0_CFG_ACT_TO_RDWR(caltim0) +
		      CALTIMING4_CFG_PCH_TO_VALID(caltim4));

	ddr_sch_writel(plat, ((CALTIMING0_CFG_ACT_TO_ACT(caltim0) <<
			 DDR_SCH_DDRTIMING_ACTTOACT_OFF) |
			(update_value << DDR_SCH_DDRTIMING_RDTOMISS_OFF) |
			(io48_value << DDR_SCH_DDRTIMING_WRTOMISS_OFF) |
			((burst_len >> 2) << DDR_SCH_DDRTIMING_BURSTLEN_OFF) |
			(CALTIMING1_CFG_RD_TO_WR(caltim1) <<
			 DDR_SCH_DDRTIMING_RDTOWR_OFF) |
			(CALTIMING3_CFG_WR_TO_RD(caltim3) <<
			 DDR_SCH_DDRTIMING_WRTORD_OFF) |
			(((ddrioctl == 1) ? 1 : 0) <<
			 DDR_SCH_DDRTIMING_BWRATIO_OFF)),
			DDR_SCH_DDRTIMING);

	/* Configure DDR mode [precharge = 0] */
	ddr_sch_writel(plat, ((ddrioctl ? 0 : 1) <<
			 DDR_SCH_DDRMOD_BWRATIOEXTENDED_OFF),
			DDR_SCH_DDRMODE);

	/* Configure the read latency */
	ddr_sch_writel(plat, (DRAMTIMING0_CFG_TCL(dramtim0) >> 1) +
			DDR_READ_LATENCY_DELAY,
			DDR_SCH_READ_LATENCY);

	/*
	 * Configuring timing values concerning activate commands
	 * [FAWBANK alway 1 because always 4 bank DDR]
	 */
	ddr_sch_writel(plat, ((CALTIMING0_CFG_ACT_TO_ACT_DB(caltim0) <<
			 DDR_SCH_ACTIVATE_RRD_OFF) |
			(CALTIMING9_CFG_4_ACT_TO_ACT(caltim9) <<
			 DDR_SCH_ACTIVATE_FAW_OFF) |
			(DDR_ACTIVATE_FAWBANK <<
			 DDR_SCH_ACTIVATE_FAWBANK_OFF)),
			DDR_SCH_ACTIVATE);

	/*
	 * Configuring timing values concerning device to device data bus
	 * ownership change
	 */
	ddr_sch_writel(plat, ((CALTIMING1_CFG_RD_TO_RD_DC(caltim1) <<
			 DDR_SCH_DEVTODEV_BUSRDTORD_OFF) |
			(CALTIMING1_CFG_RD_TO_WR_DC(caltim1) <<
			 DDR_SCH_DEVTODEV_BUSRDTOWR_OFF) |
			(CALTIMING3_CFG_WR_TO_RD_DC(caltim3) <<
			 DDR_SCH_DEVTODEV_BUSWRTORD_OFF)),
			DDR_SCH_DEVTODEV);

	/* assigning the SDRAM size */
	unsigned long long size = sdram_calculate_size(plat);
	/* If the size is invalid, use default Config size */
	if (size <= 0)
		hw_size = PHYS_SDRAM_1_SIZE;
	else
		hw_size = size;

	/* Get bank configuration from devicetree */
	ret = fdtdec_decode_ram_size(gd->fdt_blob, NULL, 0, NULL,
				     (phys_size_t *)&gd->ram_size, &bd);
	if (ret) {
		puts("DDR: Failed to decode memory node\n");
		return -1;
	}

	if (gd->ram_size != hw_size)
		printf("DDR: Warning: DRAM size from device tree mismatch with hardware.\n");

	printf("DDR: %lld MiB\n", gd->ram_size >> 20);

	/* Enable or disable the SDRAM ECC */
	if (CTRLCFG1_CFG_CTRL_EN_ECC(ctrlcfg1)) {
		setbits_le32(plat->hmc + ECCCTRL1,
			     (DDR_HMC_ECCCTL_AWB_CNT_RST_SET_MSK |
			      DDR_HMC_ECCCTL_CNT_RST_SET_MSK |
			      DDR_HMC_ECCCTL_ECC_EN_SET_MSK));
		clrbits_le32(plat->hmc + ECCCTRL1,
			     (DDR_HMC_ECCCTL_AWB_CNT_RST_SET_MSK |
			      DDR_HMC_ECCCTL_CNT_RST_SET_MSK));
		setbits_le32(plat->hmc + ECCCTRL2,
			     (DDR_HMC_ECCCTL2_RMW_EN_SET_MSK |
			      DDR_HMC_ECCCTL2_AWB_EN_SET_MSK));
		hmc_ecc_writel(plat, DDR_HMC_ERRINTEN_INTMASK, ERRINTENS);

		/* Initialize memory content if not from warm reset */
		if (!cpu_has_been_warmreset())
			sdram_init_ecc_bits(&bd);
	} else {
		clrbits_le32(plat->hmc + ECCCTRL1,
			     (DDR_HMC_ECCCTL_AWB_CNT_RST_SET_MSK |
			      DDR_HMC_ECCCTL_CNT_RST_SET_MSK |
			      DDR_HMC_ECCCTL_ECC_EN_SET_MSK));
		clrbits_le32(plat->hmc + ECCCTRL2,
			     (DDR_HMC_ECCCTL2_RMW_EN_SET_MSK |
			      DDR_HMC_ECCCTL2_AWB_EN_SET_MSK));
	}

	/* Enable non-secure reads/writes to HMC Adapter for SDRAM ECC */
	writel(FW_HMC_ADAPTOR_MPU_MASK, FW_HMC_ADAPTOR_REG_ADDR);

	sdram_size_check(&bd);

	priv->info.base = bd.bi_dram[0].start;
	priv->info.size = gd->ram_size;

	debug("DDR: HMC init success\n");
	return 0;
}

