/*
 * (C) Copyright 2007
 * Niklaus Giger (Niklaus.Giger@netstal.com)
 * (C) Copyright 2006
 * Sylvie Gohl,             AMCC/IBM, gohl.sylvie@fr.ibm.com
 * Jacqueline Pira-Ferriol, AMCC/IBM, jpira-ferriol@fr.ibm.com
 * Thierry Roman,           AMCC/IBM, thierry_roman@fr.ibm.com
 * Alain Saurel,            AMCC/IBM, alain.saurel@fr.ibm.com
 * Robert Snyder,           AMCC/IBM, rob.snyder@fr.ibm.com
 *
 * (C) Copyright 2006
 * Stefan Roese, DENX Software Engineering, sr@denx.de.
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public License as
 * published by the Free Software Foundation; either version 2 of
 * the License, or (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
 * MA 02111-1307 USA
 */

/* define DEBUG for debug output */
#undef DEBUG

#include <common.h>
#include <asm/processor.h>
#include <asm/io.h>
#include <asm/mmu.h>
#include <asm/cache.h>
#include <asm/ppc440.h>

void hcu_led_set(u32 value);
void dcbz_area(u32 start_address, u32 num_bytes);

#define ECC_RAM				0x03267F0B
#define NO_ECC_RAM			0x00267F0B

#define HCU_HW_SDRAM_CONFIG_MASK	0x7

#define MY_TLB_WORD2_I_ENABLE TLB_WORD2_I_ENABLE
	/* disable caching on DDR2 */

void board_add_ram_info(int use_default)
{
	PPC4xx_SYS_INFO board_cfg;
	u32 val;

	mfsdram(DDR0_22, val);
	val &= DDR0_22_CTRL_RAW_MASK;
	switch (val) {
	case DDR0_22_CTRL_RAW_ECC_DISABLE:
		puts(" (ECC disabled");
		break;
	case DDR0_22_CTRL_RAW_ECC_CHECK_ONLY:
		puts(" (ECC check only");
		break;
	case DDR0_22_CTRL_RAW_NO_ECC_RAM:
		puts(" (no ECC ram");
		break;
	case DDR0_22_CTRL_RAW_ECC_ENABLE:
		puts(" (ECC enabled");
		break;
	}

	get_sys_info(&board_cfg);
	printf(", %lu MHz", (board_cfg.freqPLB * 2) / 1000000);

	mfsdram(DDR0_03, val);
	val = DDR0_03_CASLAT_DECODE(val);
	printf(", CL%d)", val);
}

/*--------------------------------------------------------------------
 * wait_for_dlllock.
 *--------------------------------------------------------------------*/
static int wait_for_dlllock(void)
{
	unsigned long val;
	int wait = 0;

	/* -----------------------------------------------------------+
	 * Wait for the DCC master delay line to finish calibration
	 * ----------------------------------------------------------*/
	mtdcr(SDRAM0_CFGADDR, DDR0_17);
	val = DDR0_17_DLLLOCKREG_UNLOCKED;

	while (wait != 0xffff) {
		val = mfdcr(SDRAM0_CFGDATA);
		if ((val & DDR0_17_DLLLOCKREG_MASK) ==
		    DDR0_17_DLLLOCKREG_LOCKED)
			/* dlllockreg bit on */
			return 0;
		else
			wait++;
	}
	debug("0x%04x: DDR0_17 Value (dlllockreg bit): 0x%08x\n", wait, val);
	debug("Waiting for dlllockreg bit to raise\n");

	return -1;
}

/***********************************************************************
 *
 * sdram_panic -- Panic if we cannot configure the sdram correctly
 *
 ************************************************************************/
void sdram_panic(const char *reason)
{
	printf("\n%s: reason %s",  __FUNCTION__,  reason);
	hcu_led_set(0xff);
	while (1) {
	}
	/* Never return */
}

#ifdef CONFIG_DDR_ECC
void blank_string(int size)
{
	int i;

	for (i=0; i<size; i++)
		putc('\b');
	for (i=0; i<size; i++)
		putc(' ');
	for (i=0; i<size; i++)
		putc('\b');
}
/*---------------------------------------------------------------------------+
 * program_ecc.
 *---------------------------------------------------------------------------*/
static void program_ecc(unsigned long start_address, unsigned long num_bytes)
{
	u32 val;
	char str[] = "ECC generation -";
#if defined(CONFIG_PRAM)
	u32 *magicPtr;
	u32 magic;

	if ((mfspr(SPRN_DBCR0) & 0x80000000) == 0) {
		/* only if no external debugger is alive!
		 * Check whether vxWorks is using EDR logging, if yes zero
		 * also PostMortem and user reserved memory
		 */
		magicPtr = (u32 *)(start_address + num_bytes -
				(CONFIG_PRAM*1024) + sizeof(u32));
		magic = in_be32(magicPtr);
		debug("%s:  CONFIG_PRAM %d kB magic 0x%x 0x%p\n",
		      __FUNCTION__, CONFIG_PRAM,
		      magicPtr, magic);
		if (magic == 0xbeefbabe) {
			printf("%s: preserving at %p\n", __FUNCTION__, magicPtr);
			num_bytes -= (CONFIG_PRAM*1024) - PM_RESERVED_MEM;
		}
	}
#endif

	sync();

	puts(str);

	/* ECC bit set method for cached memory */
	/* Fast method, no noticeable delay */
	dcbz_area(start_address, num_bytes);
	/* Write modified dcache lines back to memory */
	clean_dcache_range(start_address, start_address + num_bytes);
	blank_string(strlen(str));

	/* Clear error status */
	mfsdram(DDR0_00, val);
	mtsdram(DDR0_00, val | DDR0_00_INT_ACK_ALL);

	/*
	 * Clear possible ECC errors
	 * If not done, then we could get an interrupt later on when
	 * exceptions are enabled.
	 */
	mtspr(SPRN_MCSR, mfspr(SPRN_MCSR));

	/* Set 'int_mask' parameter to functionnal value */
	mfsdram(DDR0_01, val);
	mtsdram(DDR0_01, ((val &~ DDR0_01_INT_MASK_MASK) |
			  DDR0_01_INT_MASK_ALL_OFF));

	return;
}
#endif


/***********************************************************************
 *
 * initdram -- 440EPx's DDR controller is a DENALI Core
 *
 ************************************************************************/
phys_size_t initdram (int board_type)
{
	unsigned int dram_size = 0;

	mtsdram(DDR0_02, 0x00000000);

	/* Values must be kept in sync with Excel-table <<A0001492.>> ! */
	mtsdram(DDR0_00, 0x0000190A);
	mtsdram(DDR0_01, 0x01000000);
	mtsdram(DDR0_03, 0x02030602);
	mtsdram(DDR0_04, 0x0A020200);
	mtsdram(DDR0_05, 0x02020307);
	switch (in_be16((u16 *)HCU_HW_VERSION_REGISTER) & HCU_HW_SDRAM_CONFIG_MASK) {
	case 1:
		dram_size = 256 * 1024 * 1024 ;
		mtsdram(DDR0_06, 0x0102C812);  /* 256MB RAM */
		mtsdram(DDR0_11, 0x0014C800);  /* 256MB RAM */
		mtsdram(DDR0_43, 0x030A0200);  /* 256MB RAM */
		break;
	case 0:
	default:
		dram_size = 128 * 1024 * 1024 ;
		mtsdram(DDR0_06, 0x0102C80D);  /* 128MB RAM */
		mtsdram(DDR0_11, 0x000FC800);  /* 128MB RAM */
		mtsdram(DDR0_43, 0x030A0300);  /* 128MB RAM */
		break;
	}
	mtsdram(DDR0_07, 0x00090100);

	/*
	 * TCPD=200 cycles of clock input is required to lock the DLL.
	 * CKE must be HIGH the entire time.mtsdram(DDR0_08, 0x02C80001);
	 */
	mtsdram(DDR0_08, 0x02C80001);
	mtsdram(DDR0_09, 0x00011D5F);
	mtsdram(DDR0_10, 0x00000100);
	mtsdram(DDR0_12, 0x00000003);
	mtsdram(DDR0_14, 0x00000000);
	mtsdram(DDR0_17, 0x1D000000);
	mtsdram(DDR0_18, 0x1D1D1D1D);
	mtsdram(DDR0_19, 0x1D1D1D1D);
	mtsdram(DDR0_20, 0x0B0B0B0B);
	mtsdram(DDR0_21, 0x0B0B0B0B);
#ifdef CONFIG_DDR_ECC
	mtsdram(DDR0_22, ECC_RAM);
#else
	mtsdram(DDR0_22, NO_ECC_RAM);
#endif

	mtsdram(DDR0_23, 0x00000000);
	mtsdram(DDR0_24, 0x01020001);
	mtsdram(DDR0_26, 0x2D930517);
	mtsdram(DDR0_27, 0x00008236);
	mtsdram(DDR0_28, 0x00000000);
	mtsdram(DDR0_31, 0x00000000);
	mtsdram(DDR0_42, 0x01000006);
	mtsdram(DDR0_44, 0x00000003);
	mtsdram(DDR0_02, 0x00000001);
	wait_for_dlllock();
	mtsdram(DDR0_00, 0x40000000);  /* Zero init bit */

	/*
	 * Program tlb entries for this size (dynamic)
	 */
	remove_tlb(CONFIG_SYS_SDRAM_BASE, 256 << 20);
	program_tlb(0, 0, dram_size, TLB_WORD2_W_ENABLE | TLB_WORD2_I_ENABLE);

	/*
	 * Setup 2nd TLB with same physical address but different virtual
	 * address with cache enabled. This is done for fast ECC generation.
	 */
	program_tlb(0, CONFIG_SYS_DDR_CACHED_ADDR, dram_size, 0);

#ifdef CONFIG_DDR_ECC
	/*
	 * If ECC is enabled, initialize the parity bits.
	 */
	program_ecc(CONFIG_SYS_DDR_CACHED_ADDR, dram_size);
#endif

	return (dram_size);
}
