/*
 * Copyright 2007,2009 Wind River Systems, Inc. <www.windriver.com>
 *
 * Copyright 2007 Embedded Specialties, Inc.
 *
 * Copyright 2004, 2007 Freescale Semiconductor.
 *
 * (C) Copyright 2002 Scott McNutt <smcnutt@artesyncp.com>
 *
 * SPDX-License-Identifier:	GPL-2.0+ 
 */

#include <common.h>
#include <pci.h>
#include <asm/processor.h>
#include <asm/immap_85xx.h>
#include <asm/fsl_pci.h>
#include <asm/fsl_ddr_sdram.h>
#include <asm/fsl_serdes.h>
#include <spd_sdram.h>
#include <netdev.h>
#include <tsec.h>
#include <miiphy.h>
#include <libfdt.h>
#include <fdt_support.h>

DECLARE_GLOBAL_DATA_PTR;

void local_bus_init(void);

int board_early_init_f (void)
{
	return 0;
}

int checkboard (void)
{
	volatile ccsr_local_ecm_t *ecm = (void *)(CONFIG_SYS_MPC85xx_ECM_ADDR);
	volatile u_char *rev= (void *)CONFIG_SYS_BD_REV;

	printf ("Board: Wind River SBC8548 Rev. 0x%01x\n",
			in_8(rev) >> 4);

	/*
	 * Initialize local bus.
	 */
	local_bus_init ();

	out_be32(&ecm->eedr, 0xffffffff);	/* clear ecm errors */
	out_be32(&ecm->eeer, 0xffffffff);	/* enable ecm errors */
	return 0;
}

/*
 * Initialize Local Bus
 */
void
local_bus_init(void)
{
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;

	uint clkdiv, lbc_mhz, lcrr = CONFIG_SYS_LBC_LCRR;
	sys_info_t sysinfo;

	get_sys_info(&sysinfo);

	lbc_mhz = sysinfo.freqLocalBus / 1000000;
	clkdiv = sysinfo.freqSystemBus / sysinfo.freqLocalBus;

	debug("LCRR=0x%x, CD=%d, MHz=%d\n", lcrr, clkdiv, lbc_mhz);

	out_be32(&gur->lbiuiplldcr1, 0x00078080);
	if (clkdiv == 16) {
		out_be32(&gur->lbiuiplldcr0, 0x7c0f1bf0);
	} else if (clkdiv == 8) {
		out_be32(&gur->lbiuiplldcr0, 0x6c0f1bf0);
	} else if (clkdiv == 4) {
		out_be32(&gur->lbiuiplldcr0, 0x5c0f1bf0);
	}

	/*
	 * Local Bus Clock > 83.3 MHz. According to timing
	 * specifications set LCRR[EADC] to 2 delay cycles.
	 */
	if (lbc_mhz > 83) {
		lcrr &= ~LCRR_EADC;
		lcrr |= LCRR_EADC_2;
	}

	/*
	 * According to MPC8548ERMAD Rev. 1.3, 13.3.1.16, 13-30
	 * disable PLL bypass for Local Bus Clock > 83 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");

	 /*
	 * According to MPC8548ERMAD Rev.1.3 read back LCRR
	 * and terminate with isync
	 */
	lcrr = in_be32(&lbc->lcrr);
	asm ("isync;");

	/* let DLL stabilize */
	udelay(500);

	out_be32(&lbc->ltesr, 0xffffffff);	/* Clear LBC error IRQs */
	out_be32(&lbc->lteir, 0xffffffff);	/* Enable LBC error IRQs */
}

/*
 * Initialize SDRAM memory on the Local Bus.
 */
void lbc_sdram_init(void)
{
#if defined(CONFIG_SYS_LBC_SDRAM_SIZE)

	uint idx;
	const unsigned long size = CONFIG_SYS_LBC_SDRAM_SIZE * 1024 * 1024;
	volatile fsl_lbc_t *lbc = LBC_BASE_ADDR;
	uint *sdram_addr = (uint *)CONFIG_SYS_LBC_SDRAM_BASE;
	uint *sdram_addr2 = (uint *)(CONFIG_SYS_LBC_SDRAM_BASE + size/2);

	puts("    SDRAM: ");

	print_size(size, "\n");

	/*
	 * Setup SDRAM Base and Option Registers
	 */
	set_lbc_or(3, CONFIG_SYS_OR3_PRELIM);
	set_lbc_br(3, CONFIG_SYS_BR3_PRELIM);
	set_lbc_or(4, CONFIG_SYS_OR4_PRELIM);
	set_lbc_br(4, CONFIG_SYS_BR4_PRELIM);

	out_be32(&lbc->lbcr, CONFIG_SYS_LBC_LBCR);
	asm("msync");

	out_be32(&lbc->lsrt,  CONFIG_SYS_LBC_LSRT);
	out_be32(&lbc->mrtpr, CONFIG_SYS_LBC_MRTPR);
	asm("msync");

	/*
	 * Issue PRECHARGE ALL command.
	 */
	out_be32(&lbc->lsdmr, CONFIG_SYS_LBC_LSDMR_PCHALL);
	asm("sync;msync");
	*sdram_addr = 0xff;
	ppcDcbf((unsigned long) sdram_addr);
	*sdram_addr2 = 0xff;
	ppcDcbf((unsigned long) sdram_addr2);
	udelay(100);

	/*
	 * Issue 8 AUTO REFRESH commands.
	 */
	for (idx = 0; idx < 8; idx++) {
		out_be32(&lbc->lsdmr, CONFIG_SYS_LBC_LSDMR_ARFRSH);
		asm("sync;msync");
		*sdram_addr = 0xff;
		ppcDcbf((unsigned long) sdram_addr);
		*sdram_addr2 = 0xff;
		ppcDcbf((unsigned long) sdram_addr2);
		udelay(100);
	}

	/*
	 * Issue 8 MODE-set command.
	 */
	out_be32(&lbc->lsdmr, CONFIG_SYS_LBC_LSDMR_MRW);
	asm("sync;msync");
	*sdram_addr = 0xff;
	ppcDcbf((unsigned long) sdram_addr);
	*sdram_addr2 = 0xff;
	ppcDcbf((unsigned long) sdram_addr2);
	udelay(100);

	/*
	 * Issue RFEN command.
	 */
	out_be32(&lbc->lsdmr, CONFIG_SYS_LBC_LSDMR_RFEN);
	asm("sync;msync");
	*sdram_addr = 0xff;
	ppcDcbf((unsigned long) sdram_addr);
	*sdram_addr2 = 0xff;
	ppcDcbf((unsigned long) sdram_addr2);
	udelay(200);    /* Overkill. Must wait > 200 bus cycles */

#endif	/* enable SDRAM init */
}

#if defined(CONFIG_SYS_DRAM_TEST)
int
testdram(void)
{
	uint *pstart = (uint *) CONFIG_SYS_MEMTEST_START;
	uint *pend = (uint *) CONFIG_SYS_MEMTEST_END;
	uint *p;

	printf("Testing DRAM from 0x%08x to 0x%08x\n",
	       CONFIG_SYS_MEMTEST_START,
	       CONFIG_SYS_MEMTEST_END);

	printf("DRAM test phase 1:\n");
	for (p = pstart; p < pend; p++)
		*p = 0xaaaaaaaa;

	for (p = pstart; p < pend; p++) {
		if (*p != 0xaaaaaaaa) {
			printf ("DRAM test fails at: %08x\n", (uint) p);
			return 1;
		}
	}

	printf("DRAM test phase 2:\n");
	for (p = pstart; p < pend; p++)
		*p = 0x55555555;

	for (p = pstart; p < pend; p++) {
		if (*p != 0x55555555) {
			printf ("DRAM test fails at: %08x\n", (uint) p);
			return 1;
		}
	}

	printf("DRAM test passed.\n");
	return 0;
}
#endif

#ifdef CONFIG_PCI1
static struct pci_controller pci1_hose;
#endif	/* CONFIG_PCI1 */

#ifdef CONFIG_PCI
void
pci_init_board(void)
{
	volatile ccsr_gur_t *gur = (void *)(CONFIG_SYS_MPC85xx_GUTS_ADDR);
	int first_free_busno = 0;

#ifdef CONFIG_PCI1
	struct fsl_pci_info pci_info;
	u32 devdisr = in_be32(&gur->devdisr);
	u32 pordevsr = in_be32(&gur->pordevsr);
	u32 porpllsr = in_be32(&gur->porpllsr);

	if (!(devdisr & MPC85xx_DEVDISR_PCI1)) {
		uint pci_32 = pordevsr & MPC85xx_PORDEVSR_PCI1_PCI32;
		uint pci_arb = pordevsr & MPC85xx_PORDEVSR_PCI1_ARB;
		uint pci_clk_sel = porpllsr & MPC85xx_PORDEVSR_PCI1_SPD;
		uint pci_speed = CONFIG_SYS_CLK_FREQ;	/* get_clock_freq() */

		printf("PCI: Host, %d bit, %s MHz, %s, %s\n",
			(pci_32) ? 32 : 64,
			(pci_speed == 33000000) ? "33" :
			(pci_speed == 66000000) ? "66" : "unknown",
			pci_clk_sel ? "sync" : "async",
			pci_arb ? "arbiter" : "external-arbiter");

		SET_STD_PCI_INFO(pci_info, 1);
		set_next_law(pci_info.mem_phys,
			law_size_bits(pci_info.mem_size), pci_info.law);
		set_next_law(pci_info.io_phys,
			law_size_bits(pci_info.io_size), pci_info.law);

		first_free_busno = fsl_pci_init_port(&pci_info,
					&pci1_hose, first_free_busno);
	} else {
		printf("PCI: disabled\n");
	}

	puts("\n");
#else
	setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCI1); /* disable */
#endif

	setbits_be32(&gur->devdisr, MPC85xx_DEVDISR_PCI2); /* disable PCI2 */

	fsl_pcie_init_board(first_free_busno);
}
#endif

int board_eth_init(bd_t *bis)
{
	tsec_standard_init(bis);
	pci_eth_init(bis);
	return 0;	/* otherwise cpu_eth_init gets run */
}

int last_stage_init(void)
{
	return 0;
}

#if defined(CONFIG_OF_BOARD_SETUP)
void ft_board_setup(void *blob, bd_t *bd)
{
	ft_cpu_setup(blob, bd);

#ifdef CONFIG_FSL_PCI_INIT
	FT_FSL_PCI_SETUP;
#endif
}
#endif
