#include <stdint.h>
#include <arch/io.h>
#include "cpc710.h"

#define MCCR_DEFAULT			\
	CPC710_MCCR_DIAG_MODE 		| \
	CPC710_MCCR_ECC_DISABLE 	| \
	CPC710_MCCR_REFRESH_7CY		| \
	CPC710_MCCR_DATA_MASK		| \
	CPC710_MCCR_FIXED_BITS

void cpc710_init(void);
void sdram_init(void);
extern void cpc710_pci_init(void);

void
setCPC710(uint32_t addr, uint32_t data)
{
	out_be32((unsigned *)(CPC710_PHYS_CPC0 + addr), data);
}

uint32_t
getCPC710(uint32_t addr)
{
	return (uint32_t)in_be32((unsigned *)(CPC710_PHYS_CPC0 + addr));
}

void
memory_init(void)
{
	cpc710_init();
	sdram_init();
	cpc710_pci_init();
}

void
cpc710_init(void)
{
	setCPC710(CPC710_CPC0_RSTR,   0xf0000000);	
	(void)getCPC710(CPC710_CPC0_MPSR);	
	setCPC710(CPC710_CPC0_SIOC0,   0x00000000);	
	setCPC710(CPC710_CPC0_PIDR,   0x00000000);	
	setCPC710(CPC710_CPC0_UCTL,   0x00780000);	
	setCPC710(CPC710_CPC0_ABCNTL, 0x00000000);	
	setCPC710(CPC710_CPC0_SRST,   0x00000000);	
	setCPC710(CPC710_CPC0_ERRC,   0x00000000);	
	setCPC710(CPC710_CPC0_SESR,   0x00000000);	
	setCPC710(CPC710_CPC0_SEAR,   0x00000000);	
	setCPC710(CPC710_CPC0_PGCHP,  0x000000e0);	
	setCPC710(CPC710_CPC0_GPDIR,  0x40000000);	
	setCPC710(CPC710_CPC0_GPOUT,  0x40000000);	
	setCPC710(CPC710_CPC0_ATAS,   0x709c2508);	
	setCPC710(CPC710_CPC0_AVDG,   0x00000000);	
	setCPC710(CPC710_SDRAM0_MESR,   0x00000000);	
	setCPC710(CPC710_SDRAM0_MEAR,   0x00000000);	
	setCPC710(CPC710_SDRAM0_MWPR,   0x00000000);	
	setCPC710(CPC710_CPC0_RGBAN1, 0x00000000);	
}

void
sdram_init()
{
	uint32_t mccr;

	/*
	 * Reset memory configuration
	 */
	setCPC710(CPC710_SDRAM0_MCER0,  0x00000000);	
	setCPC710(CPC710_SDRAM0_MCER1,  0x00000000);	
	setCPC710(CPC710_SDRAM0_MCER2,  0x00000000);	
	setCPC710(CPC710_SDRAM0_MCER3,  0x00000000);	
	setCPC710(CPC710_SDRAM0_MCER4,  0x00000000);	
	setCPC710(CPC710_SDRAM0_MCER5,  0x00000000);	
	setCPC710(CPC710_SDRAM0_MCER6,  0x00000000);	
	setCPC710(CPC710_SDRAM0_MCER7,  0x00000000);	
	setCPC710(CPC710_SDRAM0_MCCR,   MCCR_DEFAULT);	

	/*
	 * Temoporarily configure memory. This will be
	 * replaced by i2c later.
	 */
	setCPC710(CPC710_SDRAM0_MCER0,  0x80000080);	
	setCPC710(CPC710_SDRAM0_MCER1,  0x82000080);	
	setCPC710(CPC710_SDRAM0_MCCR,   0xd2b06000);	

	/*
 	 * wait for SDRAM init
	 */
	do {
		mccr = getCPC710(CPC710_SDRAM0_MCCR);	
	} while (mccr & CPC710_MCCR_INIT_STATUS != CPC710_MCCR_INIT_STATUS);
}
