/*
 * Copyright (C) 2006 Mindspeed Technologies Inc.
 *
 * 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
 *
 */

#include <common.h>
#include <config.h>
#include <asm/mach-types.h>
#include <asm/arch/bsp.h>
#include <asm/hardware.h>
DECLARE_GLOBAL_DATA_PTR;

static int board_detect(void)
{
	u32 gpbt;
	gpbt = (__le32_to_cpu(*(volatile u32*)(GPIO_BOOTSTRAP_REG)) & 0x1C00) >> 10 ;
	return(gpbt);
}

u32 get_ddr_size(void)
{
	u32 ddr_size = 0;
	u32 board_config;

	board_config = board_detect();

	switch (board_config) {
	case BOARD_CFG_1:
	case BOARD_CFG_6:
	default:
		ddr_size = (256 * 1024 * 1024); /* 256MB */
		break;

	case BOARD_CFG_2:
	case BOARD_CFG_3:
		ddr_size = (1024 * 1024 * 1024); /* 1024MB */
		break;
	}

	return ddr_size;
}

void bsp_init(void)
{
	u32 board_config;

        /* If MAGIC Number is present, low level initialization is done */
        if(__le64_to_cpu(*(u64*)(ARAM_BASEADDR+0x8000))  == COMCERTO_PART_MAGIC)
                return;

	SoC_Check_Device();
	SoC_APB_setup();
	SoC_AHB_setup();
	SoC_ARAM_setup();

	SoC_PLL_init();

	board_config = board_detect();
	if ((board_config != BOARD_CFG_1) && (board_config != BOARD_CFG_2) && (board_config != BOARD_CFG_3) && (board_config != BOARD_CFG_6)) {

		while(1);
	}

	icache_enable();
	SoC_mem_init(board_config);
//	SoC_nand_init();
}


int board_init(void)
{
	/* arch number of Mindspeed Comcerto */
	gd->bd->bi_arch_number = MACH_TYPE_M825XX;

	/* adress of boot parameters */
	gd->bd->bi_boot_params = LINUX_BOOTPARAM_ADDR;

	return 0;
}

int dram_init(void)
{
	gd->bd->bi_dram[0].start = PHYS_SDRAM;
	gd->bd->bi_dram[0].size = get_ddr_size();

	return 0;
}

int misc_init_r(void)
{
	return 0;
}

#ifdef BOARD_LATE_INIT
int board_late_init(void)
{
#ifdef DDR_TRAINING_DBG
	u8 wr_dqs = 0; 
	u8 dqs_out = 0;
	u8 dqs_delay0 = 0;
	u8 dqs_delay1 = 0;
	u8 dqs_delay2 = 0;
	u8 dqs_delay3 = 0;
#endif

	printf("Reserve MSP memory\n");
	gd->bd->bi_dram[0].start += MSP_BOTTOM_MEMORY_RESERVED_SIZE;
	gd->bd->bi_dram[0].size -= MSP_BOTTOM_MEMORY_RESERVED_SIZE + MSP_TOP_MEMORY_RESERVED_SIZE;

#ifdef DDR_TRAINING_DBG
	wr_dqs = DENALI_WR_DQS; 
	dqs_out = DENALI_DQS_OUT;
	dqs_delay0 = DENALI_DQS_DELAY0;
	dqs_delay1 = DENALI_DQS_DELAY1;
	dqs_delay2 = DENALI_DQS_DELAY2;
	dqs_delay3 = DENALI_DQS_DELAY3;

#ifdef DDR_TRAINING
	printf("DDR Training : ");

#ifdef NEW_DDR_TRAINING
	printf("(NEW): ");
#endif

#else
	printf("DDR default settings : ");
#endif	
	printf("wr_dqs 0x%x dqs_out 0x%x delay0 0x%x delay1 0x%x delay2 0x%x delay3 0x%x\n", wr_dqs,dqs_out,dqs_delay0,dqs_delay1,dqs_delay2,dqs_delay3);
#endif
	return 0;
}

#endif
