// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2000-2002
 * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
 */

/*
 * m8xx.c
 *
 * CPU specific code
 *
 * written or collected and sometimes rewritten by
 * Magnus Damm <damm@bitsmart.com>
 *
 * minor modifications by
 * Wolfgang Denk <wd@denx.de>
 */

#include <common.h>
#include <cpu_func.h>
#include <display_options.h>
#include <net.h>
#include <time.h>
#include <vsprintf.h>
#include <watchdog.h>
#include <command.h>
#include <mpc8xx.h>
#include <netdev.h>
#include <asm/cache.h>
#include <asm/cpm_8xx.h>
#include <asm/global_data.h>
#include <linux/compiler.h>
#include <asm/io.h>

#if defined(CONFIG_OF_LIBFDT)
#include <linux/libfdt.h>
#include <fdt_support.h>
#endif

DECLARE_GLOBAL_DATA_PTR;

/* ------------------------------------------------------------------------- */
/* L1 i-cache                                                                */

int checkicache(void)
{
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	memctl8xx_t __iomem *memctl = &immap->im_memctl;
	u32 cacheon = rd_ic_cst() & IDC_ENABLED;
	/* probe in flash memoryarea */
	u32 k = in_be32(&memctl->memc_br0) & ~0x00007fff;
	u32 m;
	u32 lines = -1;

	wr_ic_cst(IDC_UNALL);
	wr_ic_cst(IDC_INVALL);
	wr_ic_cst(IDC_DISABLE);
	__asm__ volatile ("isync");

	while (!((m = rd_ic_cst()) & IDC_CERR2)) {
		wr_ic_adr(k);
		wr_ic_cst(IDC_LDLCK);
		__asm__ volatile ("isync");

		lines++;
		k += 0x10;	/* the number of bytes in a cacheline */
	}

	wr_ic_cst(IDC_UNALL);
	wr_ic_cst(IDC_INVALL);

	if (cacheon)
		wr_ic_cst(IDC_ENABLE);
	else
		wr_ic_cst(IDC_DISABLE);

	__asm__ volatile ("isync");

	return lines << 4;
};

/* ------------------------------------------------------------------------- */
/* L1 d-cache                                                                */
/* call with cache disabled                                                  */

static int checkdcache(void)
{
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	memctl8xx_t __iomem *memctl = &immap->im_memctl;
	u32 cacheon = rd_dc_cst() & IDC_ENABLED;
	/* probe in flash memoryarea */
	u32 k = in_be32(&memctl->memc_br0) & ~0x00007fff;
	u32 m;
	u32 lines = -1;

	wr_dc_cst(IDC_UNALL);
	wr_dc_cst(IDC_INVALL);
	wr_dc_cst(IDC_DISABLE);

	while (!((m = rd_dc_cst()) & IDC_CERR2)) {
		wr_dc_adr(k);
		wr_dc_cst(IDC_LDLCK);
		lines++;
		k += 0x10;	/* the number of bytes in a cacheline */
	}

	wr_dc_cst(IDC_UNALL);
	wr_dc_cst(IDC_INVALL);

	if (cacheon)
		wr_dc_cst(IDC_ENABLE);
	else
		wr_dc_cst(IDC_DISABLE);

	return lines << 4;
};

static int check_CPU(long clock, uint pvr, uint immr)
{
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	uint k;
	char buf[32];

	/* the highest 16 bits should be 0x0050 for a 860 */

	if (PVR_VER(pvr) != PVR_VER(PVR_8xx))
		return -1;

	k = (immr << 16) |
	    in_be16((u16 __iomem *)&immap->im_cpm.cp_dpmem[PROFF_REVNUM]);

	/*
	 * Some boards use sockets so different CPUs can be used.
	 * We have to check chip version in run time.
	 */
	switch (k) {
		/* MPC866P/MPC866T/MPC859T/MPC859DSL/MPC852T */
	case 0x08010004:		/* Rev. A.0 */
		printf("MPC866xxxZPnnA");
		break;
	case 0x08000003:		/* Rev. 0.3 */
		printf("MPC866xxxZPnn");
		break;
	case 0x09000000:		/* 870/875/880/885 */
		puts("MPC885ZPnn");
		break;

	default:
		printf("unknown MPC86x (0x%08x)", k);
		break;
	}

	printf(" at %s MHz: ", strmhz(buf, clock));

	print_size(checkicache(), " I-Cache ");
	print_size(checkdcache(), " D-Cache");

	/* do we have a FEC (860T/P or 852/859/866/885)? */

	out_be32(&immap->im_cpm.cp_fec.fec_addr_low, 0x12345678);
	if (in_be32(&immap->im_cpm.cp_fec.fec_addr_low) == 0x12345678)
		printf(" FEC present");

	putc('\n');

	return 0;
}

/* ------------------------------------------------------------------------- */

int checkcpu(void)
{
	ulong clock = gd->cpu_clk;
	uint immr = get_immr();	/* Return full IMMR contents */
	uint pvr = get_pvr();

	puts("CPU:   ");

	return check_CPU(clock, pvr, immr);
}

/* ------------------------------------------------------------------------- */

void upmconfig(uint upm, uint *table, uint size)
{
	uint i;
	uint addr = 0;
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	memctl8xx_t __iomem *memctl = &immap->im_memctl;

	for (i = 0; i < size; i++) {
		out_be32(&memctl->memc_mdr, table[i]);		/* (16-15) */
		out_be32(&memctl->memc_mcr, addr | upm);	/* (16-16) */
		addr++;
	}
}

/* ------------------------------------------------------------------------- */

int do_reset(struct cmd_tbl *cmdtp, int flag, int argc, char *const argv[])
{
	ulong msr, addr;

	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;

	/* Checkstop Reset enable */
	setbits_be32(&immap->im_clkrst.car_plprcr, PLPRCR_CSR);

	/* Interrupts and MMU off */
	__asm__ volatile ("mtspr    81, 0");
	__asm__ volatile ("mfmsr    %0" : "=r" (msr));

	msr &= ~0x1030;
	__asm__ volatile ("mtmsr    %0" : : "r" (msr));

	/*
	 * Trying to execute the next instruction at a non-existing address
	 * should cause a machine check, resulting in reset
	 *
	 * note: when CONFIG_SYS_MONITOR_BASE points to a RAM address,
	 * CONFIG_SYS_MONITOR_BASE - sizeof (ulong) is usually a valid address.
	 */
	addr = CONFIG_SYS_MONITOR_BASE - sizeof(ulong);

	((void (*)(void)) addr)();
	return 1;
}

/* ------------------------------------------------------------------------- */

/*
 * Get timebase clock frequency (like cpu_clk in Hz)
 *
 * See sections 14.2 and 14.6 of the User's Manual
 */
unsigned long get_tbclk(void)
{
	immap_t __iomem *immap = (immap_t __iomem *)CONFIG_SYS_IMMR;
	ulong oscclk, factor, pll;

	if (in_be32(&immap->im_clkrst.car_sccr) & SCCR_TBS)
		return gd->cpu_clk / 16;

	pll = in_be32(&immap->im_clkrst.car_plprcr);

#define PLPRCR_val(a) ((pll & PLPRCR_ ## a ## _MSK) >> PLPRCR_ ## a ## _SHIFT)

	/*
	 * For newer PQ1 chips (MPC866/87x/88x families), PLL multiplication
	 * factor is calculated as follows:
	 *
	 *		     MFN
	 *	     MFI + -------
	 *		   MFD + 1
	 * factor =  -----------------
	 *	     (PDF + 1) * 2^S
	 *
	 */
	factor = (PLPRCR_val(MFI) + PLPRCR_val(MFN) / (PLPRCR_val(MFD) + 1)) /
		 (PLPRCR_val(PDF) + 1) / (1 << PLPRCR_val(S));

	oscclk = gd->cpu_clk / factor;

	if ((in_be32(&immap->im_clkrst.car_sccr) & SCCR_RTSEL) == 0 ||
	    factor > 2)
		return oscclk / 4;

	return oscclk / 16;
}
