/*
 * atiat9424.c
 * Matthew Millman
 *
 */

#include <common.h>
#include <mpc824x.h>
#include <asm/processor.h>
#include <asm/mmu.h>
#include <pci.h>
#include <i2c.h>

DECLARE_GLOBAL_DATA_PTR;

#ifndef CONFIG_SYS_NO_FLASH
extern flash_info_t	flash_info[CFG_MAX_FLASH_BANKS];
#endif /* CONFIG_SYS_NO_FLASH */

int checkboard (void)
{
	char  buf[32];
	puts ("Board: Allied Telesis AT9424TS/XP\n");
	return 0;
}

long int initdram(int board_type)
{
    return CFG_MAX_RAM_SIZE;
}

/*
 * Initialize PCI Devices, report devices found.
 */


static struct pci_config_table pci_at9424T_config_table[] = 
{
	{
		0x14E4, 0xB504, PCI_ANY_ID, PCI_ANY_ID, /* Broadcom BCM56504 */
		30, PCI_ANY_ID, pci_cfgfunc_config_device,
		{ 0x82000000, 0x82000000, PCI_COMMAND_MEMORY | PCI_COMMAND_MASTER }
	}
};

struct pci_controller hose = {
	config_table: pci_at9424T_config_table,
};

int cflash_present(void)
{
	u8	temp;
	
	i2c_read(0x19, 0x00, 0x01, &temp, 1); /* read u23.1 */
	
	if (!(temp & 0x01)) /* CF_CD_N */
	{
		return 1;
	}
	
	return 0;
}

void pci_init_board(void)
{
	pci_mpc824x_init(&hose);
}

int ide_preinit(void)
{
	return (!cflash_present());
}

int board_early_init_f (void)
{
	u8 temp;
	u8 u23_port0_config = 
		0x1	|	/* IN  GBICPRES24_N */
		0x2	|	/* IN  TXFLTGBIC_24 */
		/* 0x4 */	/* OUT TXDISGBIC_24 */
		0x8	|	/* IN  GBICPRES23_N */
		0x10		/* IN  TXFLTGBIC_23 */
		/* 0x20 */	/* OUT TXDISGBIC_23 */
		/* 0x40 */	/* OUT LED_MASTER_N */
		/* 0x80 */ 	/* OUT LED_FAULT_N */
		;
		
	u8 u23_port1_config = 
		/* 0x1 */	/* OUT DEBUG_LED_N */
		/* 0x2 */	/* OUT EEPROM_WP */
		0x4	|	/* IN  UNUSED */
		0x8	|	/* IN  UNUSED */
		0x10	|	/* IN  UNUSED */
		0x20 	|	/* IN  STACK_MOD_SMART_N */
		0x40 		/* IN  STACK_MOD_PRES_N */
		/* 0x80 */ 	/* OUT IFLASH_WP1_N */
		;	
	
	u8 u27_port0_config = 
		0x1	| 	/* IN  CF_CD_N */
		0x2 	|	/* IN  RDY_CF */
		/* 0x4 */ 	/* OUT CF_RST */
		0x8	|	/* IN  UNUSED */
		0x10	|	/* IN  UNUSED */
		0x20	|	/* IN  UNUSED */
		0x40	|	/* IN  UNUSED */
		0x80		/* IN  UNUSED */
		;
			
	u8 u28_port0_config = 
		/* 0x1 */	/* OUT RSTPHY_XFP_N */
		/* 0x2 */	/* OUT MSTR_SRST_N */
		/* 0x4 */	/* OUT RSTPHY_1_N */
		/* 0x8 */	/* OUT RSTSW_1_N */
		/* 0x10 */	/* OUT IFLASH_WP2_N */
		/* 0x20 */	/* OUT WDT_SET0 */
		/* 0x40 */	/* OUT WDT_SET1 */
		/* 0x80 */	/* OUT WDT_SET2 */
		0;
					
	u8 u28_port0_initial_state = 
		/* 0x1 */	/* RSTPHY_XFP_N */
		0x2	|	/* MSTR_SRST_N */
		/* 0x4 */	/* RSTPHY_1_N */
		/* 0x8 */	/* RSTSW_1_N */
		0x10	|	/* IFLASH_WP2_N */
		0x20	|	/* WDT_SET0 */
		0x40		/* WDT_SET1 */
		/* 0x80 */	/* WDT_SET2 */
			;
	
	
	i2c_write(0x18, 0x01, 0x01, &u28_port0_initial_state, 1); /* write u28.0 */
	i2c_write(0x18, 0x03, 0x01, &u28_port0_config, 1); /* u28 */
	
	i2c_write(0x19, 0x03, 0x01, &u27_port0_config, 1); /* u27 */
	
	i2c_write(0x20, 0x06, 0x01, &u23_port0_config, 1); /* u23 */
	i2c_write(0x20, 0x07, 0x01, &u23_port1_config, 1); /* u23 */
	
	i2c_read(0x20, 0x01, 0x01, &temp, 1); /* read u23.1 */
	temp |= 0x80; /* Set IFLASH_WP1_N */
	i2c_write(0x20, 0x03, 0x01, &temp, 1); /* write u23.1 */
		
	return 0;
}
#ifdef CONFIG_MISC_INIT_R
int misc_init_r (void)
{
	return (0);
}
#endif /* CONFIG_MISC_INIT_R */

void mpc824x_board_reset(void)
{
	u8 temp;
	
	i2c_read(0x18, 0x00, 0x01, &temp, 1); /* read u28.0 */
	temp &= ~0x02; /* Clear MSTR_SRST_N */
	i2c_write(0x18, 0x01, 0x01, &temp, 1); /* write u28.0 */
}

int atl_bootrom_board_attached(void)
{
	return 0; /* no such thing on this product */
}

u32 atl_get_env_addr(void)
{
	return 0xFFFF0000;
}

u32 atl_get_offset_from_base(void)
{
	return 0x0;
}

#ifndef CONFIG_SYS_NO_FLASH
u32 atl_get_jffs2_part_size(void)
{
	return flash_info[0].size;
}
#endif /* !CONFIG_SYS_NO_FLASH */
