// SPDX-License-Identifier: GPL-2.0+
/*
 * (C) Copyright 2008
 * Sergei Poselenov, Emcraft Systems, sposelenov@emcraft.com.
 *
 * Copyright 2004 Freescale Semiconductor.
 * (C) Copyright 2002,2003, Motorola Inc.
 * Xianghua Xiao, (X.Xiao@motorola.com)
 *
 * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com>
 */

#include <common.h>
#include <clock_legacy.h>
#include <env.h>
#include <init.h>
#include <pci.h>
#include <uuid.h>
#include <asm/processor.h>
#include <asm/immap_85xx.h>
#include <ioports.h>
#include <flash.h>
#include <linux/delay.h>
#include <linux/libfdt.h>
#include <fdt_support.h>
#include <asm/io.h>
#include <i2c.h>
#include <mb862xx.h>
#include <video_fb.h>
#include "upm_table.h"

DECLARE_GLOBAL_DATA_PTR;

extern flash_info_t flash_info[];	/* FLASH chips info */
extern GraphicDevice mb862xx;

void local_bus_init (void);
ulong flash_get_size (ulong base, int banknum);

int checkboard (void)
{
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	char buf[64];
	int f;
	int i = env_get_f("serial#", buf, sizeof(buf));
#ifdef CONFIG_PCI
	char *src;
#endif

	puts("Board: Socrates");
	if (i > 0) {
		puts(", serial# ");
		puts(buf);
	}
	putc('\n');

#if defined(CONFIG_PCI) || defined(CONFIG_DM_PCI)
	/* Check the PCI_clk sel bit */
	if (in_be32(&gur->porpllsr) & (1<<15)) {
		src = "SYSCLK";
		f = CONFIG_SYS_CLK_FREQ;
	} else {
		src = "PCI_CLK";
		f = CONFIG_PCI_CLK_FREQ;
	}
	printf ("PCI1:  32 bit, %d MHz (%s)\n",	f/1000000, src);
#else
	printf ("PCI1:  disabled\n");
#endif

	/*
	 * Initialize local bus.
	 */
	local_bus_init ();
	return 0;
}

int misc_init_r (void)
{
	/*
	 * Adjust flash start and offset to detected values
	 */
	gd->bd->bi_flashstart = 0 - gd->bd->bi_flashsize;
	gd->bd->bi_flashoffset = 0;

	/*
	 * Check if boot FLASH isn't max size
	 */
	if (gd->bd->bi_flashsize < (0 - CONFIG_SYS_FLASH0)) {
		set_lbc_or(0, gd->bd->bi_flashstart |
			   (CONFIG_SYS_OR0_PRELIM & 0x00007fff));
		set_lbc_br(0, gd->bd->bi_flashstart |
			   (CONFIG_SYS_BR0_PRELIM & 0x00007fff));

		/*
		 * Re-check to get correct base address
		 */
		flash_get_size(gd->bd->bi_flashstart, CONFIG_SYS_MAX_FLASH_BANKS - 1);
	}

	/*
	 * Check if only one FLASH bank is available
	 */
	if (gd->bd->bi_flashsize != CONFIG_SYS_MAX_FLASH_BANKS * (0 - CONFIG_SYS_FLASH0)) {
		set_lbc_or(1, 0);
		set_lbc_br(1, 0);

		/*
		 * Re-do flash protection upon new addresses
		 */
		flash_protect(FLAG_PROTECT_CLEAR,
			      gd->bd->bi_flashstart, 0xffffffff,
			      &flash_info[CONFIG_SYS_MAX_FLASH_BANKS - 1]);

		/* Monitor protection ON by default */
		flash_protect(FLAG_PROTECT_SET,
			      CONFIG_SYS_MONITOR_BASE, CONFIG_SYS_MONITOR_BASE +
			      monitor_flash_len - 1,
			      &flash_info[CONFIG_SYS_MAX_FLASH_BANKS - 1]);

		/* Environment protection ON by default */
		flash_protect(FLAG_PROTECT_SET,
			      CONFIG_ENV_ADDR,
			      CONFIG_ENV_ADDR + CONFIG_ENV_SECT_SIZE - 1,
			      &flash_info[CONFIG_SYS_MAX_FLASH_BANKS - 1]);

		/* Redundant environment protection ON by default */
		flash_protect(FLAG_PROTECT_SET,
			      CONFIG_ENV_ADDR_REDUND,
			      CONFIG_ENV_ADDR_REDUND + CONFIG_ENV_SECT_SIZE - 1,
			       &flash_info[CONFIG_SYS_MAX_FLASH_BANKS - 1]);
	}

#if defined(CONFIG_DM_PCI)
	pci_init();
#endif

	return 0;
}

/*
 * Initialize Local Bus
 */
void local_bus_init (void)
{
	volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
	volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
	sys_info_t sysinfo;
	uint clkdiv;
	uint lbc_mhz;
	uint lcrr = CONFIG_SYS_LBC_LCRR;

	get_sys_info (&sysinfo);
	clkdiv = lbc->lcrr & LCRR_CLKDIV;
	lbc_mhz = sysinfo.freq_systembus / 1000000 / clkdiv;

	/* Disable PLL bypass for Local Bus Clock >= 66 MHz */
	if (lbc_mhz >= 66)
		lcrr &= ~LCRR_DBYP;	/* DLL Enabled */
	else
		lcrr |= LCRR_DBYP;	/* DLL Bypass */

	out_be32 (&lbc->lcrr, lcrr);
	asm ("sync;isync;msync");

	out_be32 (&lbc->ltesr, 0xffffffff);	/* Clear LBC error interrupts */
	out_be32 (&lbc->lteir, 0xffffffff);	/* Enable LBC error interrupts */
	out_be32 (&ecm->eedr, 0xffffffff);	/* Clear ecm errors */
	out_be32 (&ecm->eeer, 0xffffffff);	/* Enable ecm errors */

	/* Init UPMA for FPGA access */
	out_be32 (&lbc->mamr, 0x44440); /* Use a customer-supplied value */
	upmconfig(UPMA, (uint *)UPMTableA, sizeof(UPMTableA) / sizeof(int));

	/* Init UPMB for Lime controller access */
	out_be32 (&lbc->mbmr, 0x444440); /* Use a customer-supplied value */
	upmconfig(UPMB, (uint *)UPMTableB, sizeof(UPMTableB) / sizeof(int));
}

#ifdef CONFIG_BOARD_EARLY_INIT_R
int board_early_init_r (void)
{
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);

	/* set and reset the GPIO pin 2 which will reset the W83782G chip */
	out_8((unsigned char*)&gur->gpoutdr, 0x3F );
	out_be32((unsigned int*)&gur->gpiocr, 0x200 );	/* enable GPOut */
	udelay(200);
	out_8( (unsigned char*)&gur->gpoutdr, 0x1F );

	return (0);
}
#endif /* CONFIG_BOARD_EARLY_INIT_R */

#ifdef CONFIG_OF_BOARD_SETUP
int ft_board_setup(void *blob, bd_t *bd)
{
	u32 val[12];
	int rc, i = 0;

	ft_cpu_setup(blob, bd);

	/* Fixup NOR FLASH mapping */
	val[i++] = 0;				/* chip select number */
	val[i++] = 0;				/* always 0 */
	val[i++] = gd->bd->bi_flashstart;
	val[i++] = gd->bd->bi_flashsize;

#if defined(CONFIG_VIDEO_MB862xx)
	if (mb862xx.frameAdrs == CONFIG_SYS_LIME_BASE) {
		/* Fixup LIME mapping */
		val[i++] = 2;			/* chip select number */
		val[i++] = 0;			/* always 0 */
		val[i++] = CONFIG_SYS_LIME_BASE;
		val[i++] = CONFIG_SYS_LIME_SIZE;
	}
#endif

	/* Fixup FPGA mapping */
	val[i++] = 3;				/* chip select number */
	val[i++] = 0;				/* always 0 */
	val[i++] = CONFIG_SYS_FPGA_BASE;
	val[i++] = CONFIG_SYS_FPGA_SIZE;

	rc = fdt_find_and_setprop(blob, "/localbus", "ranges",
				  val, i * sizeof(u32), 1);
	if (rc)
		printf("Unable to update localbus ranges, err=%s\n",
		       fdt_strerror(rc));

	return 0;
}
#endif /* CONFIG_OF_BOARD_SETUP */

#if defined(CONFIG_OF_SEPARATE)
void *board_fdt_blob_setup(void)
{
	void *fw_dtb;

	fw_dtb = (void *)(CONFIG_SYS_TEXT_BASE - CONFIG_ENV_SECT_SIZE);
	if (fdt_magic(fw_dtb) != FDT_MAGIC) {
		printf("DTB is not passed via %x\n", (u32)fw_dtb);
		return NULL;
	}

	return fw_dtb;
}
#endif

int get_serial_clock(void)
{
	return 333333330;
}
