/*
 * Copyright 2008-2014 Freescale Semiconductor, Inc.
 *
 * SPDX-License-Identifier:	GPL-2.0
 */

#include <common.h>
#ifdef CONFIG_PPC
#include <asm/fsl_law.h>
#endif
#include <div64.h>

#include <fsl_ddr.h>
#include <fsl_immap.h>
#include <asm/io.h>
#if defined(CONFIG_FSL_LSCH2) || defined(CONFIG_FSL_LSCH3) || \
	defined(CONFIG_ARM)
#include <asm/arch/clock.h>
#endif

/* To avoid 64-bit full-divides, we factor this here */
#define ULL_2E12 2000000000000ULL
#define UL_5POW12 244140625UL
#define UL_2POW13 (1UL << 13)

#define ULL_8FS 0xFFFFFFFFULL

u32 fsl_ddr_get_version(unsigned int ctrl_num)
{
	struct ccsr_ddr __iomem *ddr;
	u32 ver_major_minor_errata;

	switch (ctrl_num) {
	case 0:
		ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
		break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1)
	case 1:
		ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
		break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2)
	case 2:
		ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
		break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3)
	case 3:
		ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
		break;
#endif
	default:
		printf("%s unexpected ctrl_num = %u\n", __func__, ctrl_num);
		return 0;
	}
	ver_major_minor_errata = (ddr_in32(&ddr->ip_rev1) & 0xFFFF) << 8;
	ver_major_minor_errata |= (ddr_in32(&ddr->ip_rev2) & 0xFF00) >> 8;

	return ver_major_minor_errata;
}

/*
 * Round up mclk_ps to nearest 1 ps in memory controller code
 * if the error is 0.5ps or more.
 *
 * If an imprecise data rate is too high due to rounding error
 * propagation, compute a suitably rounded mclk_ps to compute
 * a working memory controller configuration.
 */
unsigned int get_memory_clk_period_ps(const unsigned int ctrl_num)
{
	unsigned int data_rate = get_ddr_freq(ctrl_num);
	unsigned int result;

	/* Round to nearest 10ps, being careful about 64-bit multiply/divide */
	unsigned long long rem, mclk_ps = ULL_2E12;

	/* Now perform the big divide, the result fits in 32-bits */
	rem = do_div(mclk_ps, data_rate);
	result = (rem >= (data_rate >> 1)) ? mclk_ps + 1 : mclk_ps;

	return result;
}

/* Convert picoseconds into DRAM clock cycles (rounding up if needed). */
unsigned int picos_to_mclk(const unsigned int ctrl_num, unsigned int picos)
{
	unsigned long long clks, clks_rem;
	unsigned long data_rate = get_ddr_freq(ctrl_num);

	/* Short circuit for zero picos */
	if (!picos)
		return 0;

	/* First multiply the time by the data rate (32x32 => 64) */
	clks = picos * (unsigned long long)data_rate;
	/*
	 * Now divide by 5^12 and track the 32-bit remainder, then divide
	 * by 2*(2^12) using shifts (and updating the remainder).
	 */
	clks_rem = do_div(clks, UL_5POW12);
	clks_rem += (clks & (UL_2POW13-1)) * UL_5POW12;
	clks >>= 13;

	/* If we had a remainder greater than the 1ps error, then round up */
	if (clks_rem > data_rate)
		clks++;

	/* Clamp to the maximum representable value */
	if (clks > ULL_8FS)
		clks = ULL_8FS;
	return (unsigned int) clks;
}

unsigned int mclk_to_picos(const unsigned int ctrl_num, unsigned int mclk)
{
	return get_memory_clk_period_ps(ctrl_num) * mclk;
}

#ifdef CONFIG_PPC
void
__fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
			   unsigned int law_memctl,
			   unsigned int ctrl_num)
{
	unsigned long long base = memctl_common_params->base_address;
	unsigned long long size = memctl_common_params->total_mem;

	/*
	 * If no DIMMs on this controller, do not proceed any further.
	 */
	if (!memctl_common_params->ndimms_present) {
		return;
	}

#if !defined(CONFIG_PHYS_64BIT)
	if (base >= CONFIG_MAX_MEM_MAPPED)
		return;
	if ((base + size) >= CONFIG_MAX_MEM_MAPPED)
		size = CONFIG_MAX_MEM_MAPPED - base;
#endif
	if (set_ddr_laws(base, size, law_memctl) < 0) {
		printf("%s: ERROR (ctrl #%d, TRGT ID=%x)\n", __func__, ctrl_num,
			law_memctl);
		return ;
	}
	debug("setup ddr law base = 0x%llx, size 0x%llx, TRGT_ID 0x%x\n",
		base, size, law_memctl);
}

__attribute__((weak, alias("__fsl_ddr_set_lawbar"))) void
fsl_ddr_set_lawbar(const common_timing_params_t *memctl_common_params,
			 unsigned int memctl_interleaved,
			 unsigned int ctrl_num);
#endif

void fsl_ddr_set_intl3r(const unsigned int granule_size)
{
#ifdef CONFIG_E6500
	u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
	*mcintl3r = 0x80000000 | (granule_size & 0x1f);
	debug("Enable MCINTL3R with granule size 0x%x\n", granule_size);
#endif
}

u32 fsl_ddr_get_intl3r(void)
{
	u32 val = 0;
#ifdef CONFIG_E6500
	u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
	val = *mcintl3r;
#endif
	return val;
}

void print_ddr_info(unsigned int start_ctrl)
{
	struct ccsr_ddr __iomem *ddr =
		(struct ccsr_ddr __iomem *)(CONFIG_SYS_FSL_DDR_ADDR);

#if	defined(CONFIG_E6500) && (CONFIG_SYS_NUM_DDR_CTLRS == 3)
	u32 *mcintl3r = (void *) (CONFIG_SYS_IMMR + 0x18004);
#endif
#if (CONFIG_SYS_NUM_DDR_CTLRS > 1)
	uint32_t cs0_config = ddr_in32(&ddr->cs0_config);
#endif
	uint32_t sdram_cfg = ddr_in32(&ddr->sdram_cfg);
	int cas_lat;

#if CONFIG_SYS_NUM_DDR_CTLRS >= 2
	if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) ||
	    (start_ctrl == 1)) {
		ddr = (void __iomem *)CONFIG_SYS_FSL_DDR2_ADDR;
		sdram_cfg = ddr_in32(&ddr->sdram_cfg);
	}
#endif
#if CONFIG_SYS_NUM_DDR_CTLRS >= 3
	if ((!(sdram_cfg & SDRAM_CFG_MEM_EN)) ||
	    (start_ctrl == 2)) {
		ddr = (void __iomem *)CONFIG_SYS_FSL_DDR3_ADDR;
		sdram_cfg = ddr_in32(&ddr->sdram_cfg);
	}
#endif

	if (!(sdram_cfg & SDRAM_CFG_MEM_EN)) {
		puts(" (DDR not enabled)\n");
		return;
	}

	puts(" (DDR");
	switch ((sdram_cfg & SDRAM_CFG_SDRAM_TYPE_MASK) >>
		SDRAM_CFG_SDRAM_TYPE_SHIFT) {
	case SDRAM_TYPE_DDR1:
		puts("1");
		break;
	case SDRAM_TYPE_DDR2:
		puts("2");
		break;
	case SDRAM_TYPE_DDR3:
		puts("3");
		break;
	case SDRAM_TYPE_DDR4:
		puts("4");
		break;
	default:
		puts("?");
		break;
	}

	if (sdram_cfg & SDRAM_CFG_32_BE)
		puts(", 32-bit");
	else if (sdram_cfg & SDRAM_CFG_16_BE)
		puts(", 16-bit");
	else
		puts(", 64-bit");

	/* Calculate CAS latency based on timing cfg values */
	cas_lat = ((ddr_in32(&ddr->timing_cfg_1) >> 16) & 0xf);
	if (fsl_ddr_get_version(0) <= 0x40400)
		cas_lat += 1;
	else
		cas_lat += 2;
	cas_lat += ((ddr_in32(&ddr->timing_cfg_3) >> 12) & 3) << 4;
	printf(", CL=%d", cas_lat >> 1);
	if (cas_lat & 0x1)
		puts(".5");

	if (sdram_cfg & SDRAM_CFG_ECC_EN)
		puts(", ECC on)");
	else
		puts(", ECC off)");

#if (CONFIG_SYS_NUM_DDR_CTLRS == 3)
#ifdef CONFIG_E6500
	if (*mcintl3r & 0x80000000) {
		puts("\n");
		puts("       DDR Controller Interleaving Mode: ");
		switch (*mcintl3r & 0x1f) {
		case FSL_DDR_3WAY_1KB_INTERLEAVING:
			puts("3-way 1KB");
			break;
		case FSL_DDR_3WAY_4KB_INTERLEAVING:
			puts("3-way 4KB");
			break;
		case FSL_DDR_3WAY_8KB_INTERLEAVING:
			puts("3-way 8KB");
			break;
		default:
			puts("3-way UNKNOWN");
			break;
		}
	}
#endif
#endif
#if (CONFIG_SYS_NUM_DDR_CTLRS >= 2)
	if ((cs0_config & 0x20000000) && (start_ctrl == 0)) {
		puts("\n");
		puts("       DDR Controller Interleaving Mode: ");

		switch ((cs0_config >> 24) & 0xf) {
		case FSL_DDR_256B_INTERLEAVING:
			puts("256B");
			break;
		case FSL_DDR_CACHE_LINE_INTERLEAVING:
			puts("cache line");
			break;
		case FSL_DDR_PAGE_INTERLEAVING:
			puts("page");
			break;
		case FSL_DDR_BANK_INTERLEAVING:
			puts("bank");
			break;
		case FSL_DDR_SUPERBANK_INTERLEAVING:
			puts("super-bank");
			break;
		default:
			puts("invalid");
			break;
		}
	}
#endif

	if ((sdram_cfg >> 8) & 0x7f) {
		puts("\n");
		puts("       DDR Chip-Select Interleaving Mode: ");
		switch(sdram_cfg >> 8 & 0x7f) {
		case FSL_DDR_CS0_CS1_CS2_CS3:
			puts("CS0+CS1+CS2+CS3");
			break;
		case FSL_DDR_CS0_CS1:
			puts("CS0+CS1");
			break;
		case FSL_DDR_CS2_CS3:
			puts("CS2+CS3");
			break;
		case FSL_DDR_CS0_CS1_AND_CS2_CS3:
			puts("CS0+CS1 and CS2+CS3");
			break;
		default:
			puts("invalid");
			break;
		}
	}
}

void __weak detail_board_ddr_info(void)
{
	print_ddr_info(0);
}

void board_add_ram_info(int use_default)
{
	detail_board_ddr_info();
}

#ifdef CONFIG_FSL_DDR_SYNC_REFRESH
#define DDRC_DEBUG20_INIT_DONE	0x80000000
#define DDRC_DEBUG2_RF		0x00000040
void fsl_ddr_sync_memctl_refresh(unsigned int first_ctrl,
				 unsigned int last_ctrl)
{
	unsigned int i;
	u32 ddrc_debug20;
	u32 ddrc_debug2[CONFIG_SYS_NUM_DDR_CTLRS] = {};
	u32 *ddrc_debug2_p[CONFIG_SYS_NUM_DDR_CTLRS] = {};
	struct ccsr_ddr __iomem *ddr;

	for (i = first_ctrl; i <= last_ctrl; i++) {
		switch (i) {
		case 0:
			ddr = (void *)CONFIG_SYS_FSL_DDR_ADDR;
			break;
#if defined(CONFIG_SYS_FSL_DDR2_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 1)
		case 1:
			ddr = (void *)CONFIG_SYS_FSL_DDR2_ADDR;
			break;
#endif
#if defined(CONFIG_SYS_FSL_DDR3_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 2)
		case 2:
			ddr = (void *)CONFIG_SYS_FSL_DDR3_ADDR;
			break;
#endif
#if defined(CONFIG_SYS_FSL_DDR4_ADDR) && (CONFIG_SYS_NUM_DDR_CTLRS > 3)
		case 3:
			ddr = (void *)CONFIG_SYS_FSL_DDR4_ADDR;
			break;
#endif
		default:
			printf("%s unexpected ctrl = %u\n", __func__, i);
			return;
		}
		ddrc_debug20 = ddr_in32(&ddr->debug[19]);
		ddrc_debug2_p[i] = &ddr->debug[1];
		while (!(ddrc_debug20 & DDRC_DEBUG20_INIT_DONE)) {
			/* keep polling until DDRC init is done */
			udelay(100);
			ddrc_debug20 = ddr_in32(&ddr->debug[19]);
		}
		ddrc_debug2[i] = ddr_in32(&ddr->debug[1]) | DDRC_DEBUG2_RF;
	}
	/*
	 * Sync refresh
	 * This is put together to make sure the refresh reqeusts are sent
	 * closely to each other.
	 */
	for (i = first_ctrl; i <= last_ctrl; i++)
		ddr_out32(ddrc_debug2_p[i], ddrc_debug2[i]);
}
#endif /* CONFIG_FSL_DDR_SYNC_REFRESH */

void remove_unused_controllers(fsl_ddr_info_t *info)
{
#ifdef CONFIG_FSL_LSCH3
	int i;
	u64 nodeid;
	void *hnf_sam_ctrl = (void *)(CCI_HN_F_0_BASE + CCN_HN_F_SAM_CTL);
	bool ddr0_used = false;
	bool ddr1_used = false;

	for (i = 0; i < 8; i++) {
		nodeid = in_le64(hnf_sam_ctrl) & CCN_HN_F_SAM_NODEID_MASK;
		if (nodeid == CCN_HN_F_SAM_NODEID_DDR0) {
			ddr0_used = true;
		} else if (nodeid == CCN_HN_F_SAM_NODEID_DDR1) {
			ddr1_used = true;
		} else {
			printf("Unknown nodeid in HN-F SAM control: 0x%llx\n",
			       nodeid);
		}
		hnf_sam_ctrl += (CCI_HN_F_1_BASE - CCI_HN_F_0_BASE);
	}
	if (!ddr0_used && !ddr1_used) {
		printf("Invalid configuration in HN-F SAM control\n");
		return;
	}

	if (!ddr0_used && info->first_ctrl == 0) {
		info->first_ctrl = 1;
		info->num_ctrls = 1;
		debug("First DDR controller disabled\n");
		return;
	}

	if (!ddr1_used && info->first_ctrl + info->num_ctrls > 1) {
		info->num_ctrls = 1;
		debug("Second DDR controller disabled\n");
	}
#endif
}
