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

#include <common.h>
#include <asm/processor.h>
#include <ioports.h>
#include <lmb.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include <asm/fsl_law.h>
#include <fsl_ddr_sdram.h>
#include "mp.h"

DECLARE_GLOBAL_DATA_PTR;
u32 fsl_ddr_get_intl3r(void);

extern u32 __spin_table[];

u32 get_my_id()
{
	return mfspr(SPRN_PIR);
}

/*
 * Determine if U-Boot should keep secondary cores in reset, or let them out
 * of reset and hold them in a spinloop
 */
int hold_cores_in_reset(int verbose)
{
	/* Default to no, overriden by 'y', 'yes', 'Y', 'Yes', or '1' */
	if (getenv_yesno("mp_holdoff") == 1) {
		if (verbose) {
			puts("Secondary cores are being held in reset.\n");
			puts("See 'mp_holdoff' environment variable\n");
		}

		return 1;
	}

	return 0;
}

int cpu_reset(int nr)
{
	volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR);
	out_be32(&pic->pir, 1 << nr);
	/* the dummy read works around an errata on early 85xx MP PICs */
	(void)in_be32(&pic->pir);
	out_be32(&pic->pir, 0x0);

	return 0;
}

int cpu_status(int nr)
{
	u32 *table, id = get_my_id();

	if (hold_cores_in_reset(1))
		return 0;

	if (nr == id) {
		table = (u32 *)&__spin_table;
		printf("table base @ 0x%p\n", table);
	} else if (is_core_disabled(nr)) {
		puts("Disabled\n");
	} else {
		table = (u32 *)&__spin_table + nr * NUM_BOOT_ENTRY;
		printf("Running on cpu %d\n", id);
		printf("\n");
		printf("table @ 0x%p\n", table);
		printf("   addr - 0x%08x\n", table[BOOT_ENTRY_ADDR_LOWER]);
		printf("   r3   - 0x%08x\n", table[BOOT_ENTRY_R3_LOWER]);
		printf("   pir  - 0x%08x\n", table[BOOT_ENTRY_PIR]);
	}

	return 0;
}

#ifdef CONFIG_FSL_CORENET
int cpu_disable(int nr)
{
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);

	setbits_be32(&gur->coredisrl, 1 << nr);

	return 0;
}

int is_core_disabled(int nr) {
	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	u32 coredisrl = in_be32(&gur->coredisrl);

	return (coredisrl & (1 << nr));
}
#else
int cpu_disable(int nr)
{
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);

	switch (nr) {
	case 0:
		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_CPU0);
		break;
	case 1:
		setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_CPU1);
		break;
	default:
		printf("Invalid cpu number for disable %d\n", nr);
		return 1;
	}

	return 0;
}

int is_core_disabled(int nr) {
	ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	u32 devdisr = in_be32(&gur->devdisr);

	switch (nr) {
	case 0:
		return (devdisr & MPC85xx_DEVDISR_CPU0);
	case 1:
		return (devdisr & MPC85xx_DEVDISR_CPU1);
	default:
		printf("Invalid cpu number for disable %d\n", nr);
	}

	return 0;
}
#endif

static u8 boot_entry_map[4] = {
	0,
	BOOT_ENTRY_PIR,
	BOOT_ENTRY_R3_LOWER,
};

int cpu_release(int nr, int argc, char * const argv[])
{
	u32 i, val, *table = (u32 *)&__spin_table + nr * NUM_BOOT_ENTRY;
	u64 boot_addr;

	if (hold_cores_in_reset(1))
		return 0;

	if (nr == get_my_id()) {
		printf("Invalid to release the boot core.\n\n");
		return 1;
	}

	if (argc != 4) {
		printf("Invalid number of arguments to release.\n\n");
		return 1;
	}

	boot_addr = simple_strtoull(argv[0], NULL, 16);

	/* handle pir, r3 */
	for (i = 1; i < 3; i++) {
		if (argv[i][0] != '-') {
			u8 entry = boot_entry_map[i];
			val = simple_strtoul(argv[i], NULL, 16);
			table[entry] = val;
		}
	}

	table[BOOT_ENTRY_ADDR_UPPER] = (u32)(boot_addr >> 32);

	/* ensure all table updates complete before final address write */
	eieio();

	table[BOOT_ENTRY_ADDR_LOWER] = (u32)(boot_addr & 0xffffffff);

	return 0;
}

u32 determine_mp_bootpg(unsigned int *pagesize)
{
	u32 bootpg;
#ifdef CONFIG_SYS_FSL_ERRATUM_A004468
	u32 svr = get_svr();
	u32 granule_size, check;
	struct law_entry e;
#endif


	/* use last 4K of mapped memory */
	bootpg = ((gd->ram_size > CONFIG_MAX_MEM_MAPPED) ?
		CONFIG_MAX_MEM_MAPPED : gd->ram_size) +
		CONFIG_SYS_SDRAM_BASE - 4096;
	if (pagesize)
		*pagesize = 4096;

#ifdef CONFIG_SYS_FSL_ERRATUM_A004468
/*
 * Erratum A004468 has two parts. The 3-way interleaving applies to T4240,
 * to be fixed in rev 2.0. The 2-way interleaving applies to many SoCs. But
 * the way boot page chosen in u-boot avoids hitting this erratum. So only
 * thw workaround for 3-way interleaving is needed.
 *
 * To make sure boot page translation works with 3-Way DDR interleaving
 * enforce a check for the following constrains
 * 8K granule size requires BRSIZE=8K and
 *    bootpg >> log2(BRSIZE) %3 == 1
 * 4K and 1K granule size requires BRSIZE=4K and
 *    bootpg >> log2(BRSIZE) %3 == 0
 */
	if (SVR_SOC_VER(svr) == SVR_T4240 && SVR_MAJ(svr) < 2) {
		e = find_law(bootpg);
		switch (e.trgt_id) {
		case LAW_TRGT_IF_DDR_INTLV_123:
			granule_size = fsl_ddr_get_intl3r() & 0x1f;
			if (granule_size == FSL_DDR_3WAY_8KB_INTERLEAVING) {
				if (pagesize)
					*pagesize = 8192;
				bootpg &= 0xffffe000;	/* align to 8KB */
				check = bootpg >> 13;
				while ((check % 3) != 1)
					check--;
				bootpg = check << 13;
				debug("Boot page (8K) at 0x%08x\n", bootpg);
				break;
			} else {
				bootpg &= 0xfffff000;	/* align to 4KB */
				check = bootpg >> 12;
				while ((check % 3) != 0)
					check--;
				bootpg = check << 12;
				debug("Boot page (4K) at 0x%08x\n", bootpg);
			}
				break;
		default:
			break;
		}
	}
#endif /* CONFIG_SYS_FSL_ERRATUM_A004468 */

	return bootpg;
}

phys_addr_t get_spin_phys_addr(void)
{
	return virt_to_phys(&__spin_table);
}

#ifdef CONFIG_FSL_CORENET
static void plat_mp_up(unsigned long bootpg, unsigned int pagesize)
{
	u32 cpu_up_mask, whoami, brsize = LAW_SIZE_4K;
	u32 *table = (u32 *)&__spin_table;
	volatile ccsr_gur_t *gur;
	volatile ccsr_local_t *ccm;
	volatile ccsr_rcpm_t *rcpm;
	volatile ccsr_pic_t *pic;
	int timeout = 10;
	u32 mask = cpu_mask();
	struct law_entry e;

	gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	ccm = (void *)(CONFIG_SYS_FSL_CORENET_CCM_ADDR);
	rcpm = (void *)(CONFIG_SYS_FSL_CORENET_RCPM_ADDR);
	pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR);

	whoami = in_be32(&pic->whoami);
	cpu_up_mask = 1 << whoami;
	out_be32(&ccm->bstrl, bootpg);

	e = find_law(bootpg);
	/* pagesize is only 4K or 8K */
	if (pagesize == 8192)
		brsize = LAW_SIZE_8K;
	out_be32(&ccm->bstrar, LAW_EN | e.trgt_id << 20 | brsize);
	debug("BRSIZE is 0x%x\n", brsize);

	/* readback to sync write */
	in_be32(&ccm->bstrar);

	/* disable time base at the platform */
	out_be32(&rcpm->ctbenrl, cpu_up_mask);

	out_be32(&gur->brrl, mask);

	/* wait for everyone */
	while (timeout) {
		unsigned int i, cpu, nr_cpus = cpu_numcores();

		for_each_cpu(i, cpu, nr_cpus, mask) {
			if (table[cpu * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER])
				cpu_up_mask |= (1 << cpu);
		}

		if ((cpu_up_mask & mask) == mask)
			break;

		udelay(100);
		timeout--;
	}

	if (timeout == 0)
		printf("CPU up timeout. CPU up mask is %x should be %x\n",
			cpu_up_mask, mask);

	/* enable time base at the platform */
	out_be32(&rcpm->ctbenrl, 0);

	/* readback to sync write */
	in_be32(&rcpm->ctbenrl);

	mtspr(SPRN_TBWU, 0);
	mtspr(SPRN_TBWL, 0);

	out_be32(&rcpm->ctbenrl, mask);

#ifdef CONFIG_MPC8xxx_DISABLE_BPTR
	/*
	 * Disabling Boot Page Translation allows the memory region 0xfffff000
	 * to 0xffffffff to be used normally.  Leaving Boot Page Translation
	 * enabled remaps 0xfffff000 to SDRAM which makes that memory region
	 * unusable for normal operation but it does allow OSes to easily
	 * reset a processor core to put it back into U-Boot's spinloop.
	 */
	clrbits_be32(&ccm->bstrar, LAW_EN);
#endif
}
#else
static void plat_mp_up(unsigned long bootpg, unsigned int pagesize)
{
	u32 up, cpu_up_mask, whoami;
	u32 *table = (u32 *)&__spin_table;
	volatile u32 bpcr;
	volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	volatile ccsr_pic_t *pic = (void *)(CONFIG_SYS_MPC8xxx_PIC_ADDR);
	u32 devdisr;
	int timeout = 10;

	whoami = in_be32(&pic->whoami);
	out_be32(&ecm->bptr, 0x80000000 | (bootpg >> 12));

	/* disable time base at the platform */
	devdisr = in_be32(&gur->devdisr);
	if (whoami)
		devdisr |= MPC85xx_DEVDISR_TB0;
	else
		devdisr |= MPC85xx_DEVDISR_TB1;
	out_be32(&gur->devdisr, devdisr);

	/* release the hounds */
	up = ((1 << cpu_numcores()) - 1);
	bpcr = in_be32(&ecm->eebpcr);
	bpcr |= (up << 24);
	out_be32(&ecm->eebpcr, bpcr);
	asm("sync; isync; msync");

	cpu_up_mask = 1 << whoami;
	/* wait for everyone */
	while (timeout) {
		int i;
		for (i = 0; i < cpu_numcores(); i++) {
			if (table[i * NUM_BOOT_ENTRY + BOOT_ENTRY_ADDR_LOWER])
				cpu_up_mask |= (1 << i);
		};

		if ((cpu_up_mask & up) == up)
			break;

		udelay(100);
		timeout--;
	}

	if (timeout == 0)
		printf("CPU up timeout. CPU up mask is %x should be %x\n",
			cpu_up_mask, up);

	/* enable time base at the platform */
	if (whoami)
		devdisr |= MPC85xx_DEVDISR_TB1;
	else
		devdisr |= MPC85xx_DEVDISR_TB0;
	out_be32(&gur->devdisr, devdisr);

	/* readback to sync write */
	in_be32(&gur->devdisr);

	mtspr(SPRN_TBWU, 0);
	mtspr(SPRN_TBWL, 0);

	devdisr &= ~(MPC85xx_DEVDISR_TB0 | MPC85xx_DEVDISR_TB1);
	out_be32(&gur->devdisr, devdisr);

#ifdef CONFIG_MPC8xxx_DISABLE_BPTR
	/*
	 * Disabling Boot Page Translation allows the memory region 0xfffff000
	 * to 0xffffffff to be used normally.  Leaving Boot Page Translation
	 * enabled remaps 0xfffff000 to SDRAM which makes that memory region
	 * unusable for normal operation but it does allow OSes to easily
	 * reset a processor core to put it back into U-Boot's spinloop.
	 */
	clrbits_be32(&ecm->bptr, 0x80000000);
#endif
}
#endif

void cpu_mp_lmb_reserve(struct lmb *lmb)
{
	u32 bootpg = determine_mp_bootpg(NULL);

	lmb_reserve(lmb, bootpg, 4096);
}

void setup_mp(void)
{
	extern u32 __secondary_start_page;
	extern u32 __bootpg_addr, __spin_table_addr, __second_half_boot_page;

	int i;
	ulong fixup = (u32)&__secondary_start_page;
	u32 bootpg, bootpg_map, pagesize;

	bootpg = determine_mp_bootpg(&pagesize);

	/*
	 * pagesize is only 4K or 8K
	 * we only use the last 4K of boot page
	 * bootpg_map saves the address for the boot page
	 * 8K is used for the workaround of 3-way DDR interleaving
	 */

	bootpg_map = bootpg;

	if (pagesize == 8192)
		bootpg += 4096;	/* use 2nd half */

	/* Some OSes expect secondary cores to be held in reset */
	if (hold_cores_in_reset(0))
		return;

	/*
	 * Store the bootpg's cache-able half address for use by secondary
	 * CPU cores to continue to boot
	 */
	__bootpg_addr = (u32)virt_to_phys(&__second_half_boot_page);

	/* Store spin table's physical address for use by secondary cores */
	__spin_table_addr = (u32)get_spin_phys_addr();

	/* flush bootpg it before copying invalidate any staled cacheline */
	flush_cache(bootpg, 4096);

	/* look for the tlb covering the reset page, there better be one */
	i = find_tlb_idx((void *)CONFIG_BPTR_VIRT_ADDR, 1);

	/* we found a match */
	if (i != -1) {
		/* map reset page to bootpg so we can copy code there */
		disable_tlb(i);

		set_tlb(1, CONFIG_BPTR_VIRT_ADDR, bootpg, /* tlb, epn, rpn */
			MAS3_SX|MAS3_SW|MAS3_SR, MAS2_I|MAS2_G, /* perms, wimge */
			0, i, BOOKE_PAGESZ_4K, 1); /* ts, esel, tsize, iprot */

		memcpy((void *)CONFIG_BPTR_VIRT_ADDR, (void *)fixup, 4096);

		plat_mp_up(bootpg_map, pagesize);
	} else {
		puts("WARNING: No reset page TLB. "
			"Skipping secondary core setup\n");
	}
}
