/*
 * 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>
DECLARE_GLOBAL_DATA_PTR;

#ifdef CFG_FLASH_COMPLEX_MAPPINGS
void board_map(flash_info_t *info, unsigned long addr)
{
	if ((addr >= (PHYS_FLASH1 + 0x800000)) && (addr < (PHYS_FLASH1 + 0x1000000))) {
		SoC_gpio_set_0(SoC_gpio_mask(5));
	} else {
		SoC_gpio_set_1(SoC_gpio_mask(5));
	}
}
#endif

u32 get_ddr_size(void)
{
	return PHYS_SDRAM_SIZE;
}

static void nor_hw_init(void)
{
	/* set GPIO5 as output */
	SoC_gpio_cfg(5, GPIO_TYPE_OUTPUT);

	/* Select upper 8MiB of flash device */
	SoC_gpio_set_1(SoC_gpio_mask(5));

#ifdef CFG_FLASH_COMPLEX_MAPPINGS
	*(volatile u32 *)EX_CS0_SEG_REG = 0x7FF;
#else
	*(volatile u32 *)EX_CS0_SEG_REG = 0x3FF;
#endif

        /* adjust EXP bus configuration registers */
        *(volatile u32 *)EX_CLOCK_DIV_REG = 0x5;
        *(volatile u32 *)EX_CS0_TMG1_REG = 0x03034007;
        *(volatile u32 *)EX_CS0_TMG2_REG = 0x04040502;

}

void bsp_init(void)
{
	SoC_Check_Device();
	SoC_APB_setup();
	SoC_AHB_setup();
	SoC_ARAM_setup();

	SoC_PLL_init();

	icache_enable();
	SoC_mem_init(BOARD_CFG_MOCA);
}

int board_init(void)
{
        u32 i, led_mask;
    
	nor_hw_init();

	/* 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;

        /* force WAN Select (GPIO6) to GigE PHY, not MoCA */
	SoC_gpio_cfg(6, GPIO_TYPE_OUTPUT);
	SoC_gpio_set_1(SoC_gpio_mask(6));
        
        /* configure MoCA PHY reset lines for as GPIO outputs, hold in reset */
       	SoC_gpio_cfg(22, GPIO_TYPE_OUTPUT);
       	SoC_gpio_cfg(23, GPIO_TYPE_OUTPUT);
        SoC_gpio_set_0(SoC_gpio_mask(23) | SoC_gpio_mask(22));
        
        /* force external reset via GPIO17 for 100msec */
       	SoC_gpio_cfg(17, GPIO_TYPE_OUTPUT);
	SoC_gpio_set_1(SoC_gpio_mask(17));
        udelay(10);
	SoC_gpio_set_0(SoC_gpio_mask(17));
        udelay(100*1000);
	SoC_gpio_set_1(SoC_gpio_mask(17));
        udelay(100*1000);

	/* enable I2C interface */
	while (1)
	{
	   u32 temp;
   	   temp = *(volatile u32 *)GPIO_IOCTRL_REG | GPIO_IOCTRL_I2C; 		// enable I2C bus
   	   *(volatile u32 *)GPIO_LOCK_REG = 0x55555555; 			// remove lock
   	   *(volatile u32 *)GPIO_IOCTRL_REG = temp;				// write to ctrl reg
   	   if (*(volatile u32 *)GPIO_IOCTRL_REG == temp)
		   break;
	}

        /* configure WPS and config-reset buttons as inputs */
        SoC_gpio_cfg(3, GPIO_TYPE_INPUT);
        SoC_gpio_cfg(4, GPIO_TYPE_INPUT);

        /* configure GPIO-driven LEDs as outputs, flash them */
       	SoC_gpio_cfg(29, GPIO_TYPE_OUTPUT);
       	SoC_gpio_cfg(30, GPIO_TYPE_OUTPUT);
       	SoC_gpio_cfg(15, GPIO_TYPE_OUTPUT);
       	SoC_gpio_cfg(16, GPIO_TYPE_OUTPUT);
        led_mask = SoC_gpio_mask(29) | SoC_gpio_mask(30) | SoC_gpio_mask(15) | SoC_gpio_mask(16);
        for (i = 0; i < 10; i++) {
            if (i%2) {
                SoC_gpio_set_1(led_mask);
            } else {
                SoC_gpio_set_0(led_mask);
            }
            udelay(100*1000);
        }

	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;
	printf("DDR Training : ");
	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
