/*
 * (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 <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);
}
