/*
 * (C) Copyright IBM Corp. 2007, 2010
 *
 * 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, see <http://www.gnu.org/licenses>.
 *
 * Author: Chris Ward <tjcw@uk.ibm.com>
 *
 * Based on earlier code:
 *   Copyright (C) Paul Mackerras 1997.
 *
 *   Matt Porter <mporter@kernel.crashing.org>
 *   Copyright 2002-2005 MontaVista Software Inc.
 *
 *   Eugene Surovegin <eugene.surovegin@zultys.com> or <ebs@ebshome.net>
 *   Copyright (c) 2003, 2004 Zultys Technologies
 *
 *   David Gibson, IBM Corporation, 2007
 *
 */
#include "types.h"
#include "ops.h"
#include "stdio.h"
#include "4xx.h"
#include "44x.h"
#include "bgcns.h"
/* Types needed for the personality */
typedef u8  uint8_t;
typedef u16 uint16_t;
typedef u32 uint32_t;
#include "bgp_personality.h"

/* Blue Gene firmware jumps to 0x10.
 * Simply branch to _zimage_start which is typically 0x800000.
 * Must also link with --section-start bgstart=0
 */
asm (
"       .section bgstart, \"ax\";		"
"       .=0x10;					"
"       lis     %r9, _zimage_start@h;		"
"       ori	%r9, %r9, _zimage_start@l;	"
"       mtlr    %r9;				"
"       blr;					"
"	.previous				"
);

/* This will point directly to CNS which remains mapped on entry. */
BGCNS_Descriptor* cns;

//static void bgp_console_write(const char *msg, int len) __attribute__((unused)) ;

static void bgp_console_write(const char *msg, int len)
{
	if (cns)
		cns->services->writeToMailboxConsole((char *)msg, len);
}

static void bgp_fixup_bluegene_cns(BGCNS_Descriptor *cns)
{
	void *node = finddevice("/ibm,bluegene/cns");
	if (node) {
		setprop_val(node, "base-va", cns->baseVirtualAddress);
		setprop_val(node, "base-pa", cns->basePhysicalAddress);
		setprop_val(node, "size", cns->size);
		setprop_val(node, "services", cns->services);
		setprop_val(node, "version", cns->version);
	} else {
		fatal("could not find /ibm,bluegene/cns node in device tree");
	}
}

static void bgp_fixup_bluegene_personality(BGP_Personality_t *bgpers)
{
	void *node = finddevice("/ibm,bluegene/personality");
	if (node) {
		/* We could include individual fields of the personality as needed
		 * so that Linux doesn't need to decode the struct directly.  We
		 * provide raw-data for external tools and daemons.
		 * This can replace /proc/personality
		 */
		unsigned frequency = bgpers->Kernel_Config.FreqMHz * 1000000;
		setprop(node, "raw-data", bgpers, sizeof(*bgpers));
		setprop_val(node, "frequency", frequency);
	} else {
		fatal("could not find /ibm,bluegene/personality node in device tree");
	}
}

static void bgp_fixup_bluegene_initrd(void)
{
	void *node = finddevice("/chosen");
	if (node) {
		/* On Blue Gene we may have a gzipped ramdisk loaded at a fixed
		 * address (0x1000000).  It is preceeded by a 4-byte magic value and a
		 * 4-byte big endian length.
		 */
		unsigned *rd = (unsigned *)0x1000000;	/* 16M */

		if (rd[0] == 0xf0e1d2c3 && rd[1] != 0) {
			unsigned initrd_start = (unsigned)(rd+2);
			unsigned initrd_len = rd[1];
			unsigned initrd_end = initrd_start + initrd_len;
			setprop_val(node, "linux,initrd-start", initrd_start);
			setprop_val(node, "linux,initrd-end", initrd_end);
		}
	} else {
		fatal("could not find chosen node in device tree");
	}
}

static void bgp_fixups(void)
{
	BGP_Personality_t *bgpers = cns->services->getPersonalityData();
	unsigned int DDRSize = (bgpers->DDR_Config.DDRSizeMB << 20) - cns->size;
	unsigned int freq = bgpers->Kernel_Config.FreqMHz * 1000000;

/* For vRNIC configurations, turn down the memory that Linux thinks is on the node so the vRNIC can map it all */
	if ( (DDRSize & 0xf0000000 ) == 0xd0000000 ) DDRSize = 0xb0000000 ;

        dt_fixup_memory(0, DDRSize);
        dt_fixup_cpu_clocks(freq, freq, freq);

	bgp_fixup_bluegene_cns(cns);
	bgp_fixup_bluegene_personality(bgpers);
	bgp_fixup_bluegene_initrd();

#if 0
	 /*  FIXME: sysclk should be derived by reading the FPGA registers */
	unsigned long sysclk = 33000000;

	ibm440gp_fixup_clocks(sysclk, 6 * 1843200);
	ibm4xx_sdram_fixup_memsize();
	dt_fixup_mac_address_by_alias("ethernet0", ebony_mac0);
	dt_fixup_mac_address_by_alias("ethernet1", ebony_mac1);
	ibm4xx_fixup_ebc_ranges("/plb/opb/ebc");
	ebony_flashsel_fixup();
#endif
}


void platform_init(unsigned long r3, unsigned long r4, unsigned long r5,
                   unsigned long r6, unsigned long r7)
{
	cns = (BGCNS_Descriptor*) r3;
#if defined(CONFIG_PPC_EARLY_DEBUG_BGP)
	{
	    BGP_Personality_t bgpers;
	    
	    /* ZXXX: only rank0 prints msg */
	    if( cns ) {
		memcpy(&bgpers, cns->services->getPersonalityData(), sizeof(bgpers) );

		if( bgpers.Network_Config.Rank == 0 ) { 
		    console_ops.write = bgp_console_write;
		} else {
		    console_ops.write = 0;
		}
	    }
	}
#endif

	simple_alloc_init(_end, 256 << 20, 32, 64);

	platform_ops.fixups = bgp_fixups;
	platform_ops.exit = ibm44x_dbcr_reset;
	fdt_init(_dtb_start);

/*	serial_console_init(); */
}
