/*
 * Copyright © 2011 Tony Breeds IBM Corporation
 *
 * 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
 *
 *    Copyright 2007 David Gibson, IBM Corporation.
 *    Copyright 2010 Ben. Herrenschmidt, IBM Corporation.
 *    Copyright © 2011 David Kleikamp IBM Corporation
 *
 * 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.
 */
#include <stdarg.h>
#include <stddef.h>
#include "types.h"
#include "elf.h"
#include "string.h"
#include "stdio.h"
#include "page.h"
#include "ops.h"
#include "reg.h"
#include "io.h"
#include "dcr.h"
#include "4xx.h"
#include "44x.h"
#include "libfdt.h"

BSS_STACK(4096);

#define MAX_RANKS	0x4
#define DDR3_MR0CF	0x80010011U

static unsigned long long ibm_currituck_memsize;
static unsigned long long ibm_currituck_detect_memsize(void)
{
	u32 reg;
	unsigned i;
	unsigned long long memsize = 0;

	for(i = 0; i < MAX_RANKS; i++){
		reg = mfdcrx(DDR3_MR0CF + i);

		if (!(reg & 1))
			continue;

		reg &= 0x0000f000;
		reg >>= 12;
		memsize += (0x800000ULL << reg);
	}

	return memsize;
}

static void ibm_currituck_fixups(void)
{
	void *devp = finddevice("/");
	u32 dma_ranges[7];

	dt_fixup_memory(0x0ULL,  ibm_currituck_memsize);

	while ((devp = find_node_by_devtype(devp, "pci"))) {
		if (getprop(devp, "dma-ranges", dma_ranges, sizeof(dma_ranges)) < 0) {
			printf("%s: Failed to get dma-ranges\r\n", __func__);
			continue;
		}

		dma_ranges[5] = ibm_currituck_memsize >> 32;
		dma_ranges[6] = ibm_currituck_memsize & 0xffffffffUL;

		setprop(devp, "dma-ranges", dma_ranges, sizeof(dma_ranges));
	}
}

#define SPRN_PIR	0x11E	/* Processor Indentification Register */
void platform_init(void)
{
	unsigned long end_of_ram, avail_ram;
	u32 pir_reg;
	int node, size;
	const u32 *timebase;

	ibm_currituck_memsize = ibm_currituck_detect_memsize();
	if (ibm_currituck_memsize >> 32)
		end_of_ram = ~0UL;
	else
		end_of_ram = ibm_currituck_memsize;
	avail_ram = end_of_ram - (unsigned long)_end;

	simple_alloc_init(_end, avail_ram, 128, 64);
	platform_ops.fixups = ibm_currituck_fixups;
	platform_ops.exit = ibm44x_dbcr_reset;
	pir_reg = mfspr(SPRN_PIR);

	/* Make sure FDT blob is sane */
	if (fdt_check_header(_dtb_start) != 0)
		fatal("Invalid device tree blob\n");

	node = fdt_node_offset_by_prop_value(_dtb_start, -1, "device_type",
	                                     "cpu", sizeof("cpu"));
	if (!node)
		fatal("Cannot find cpu node\n");
	timebase = fdt_getprop(_dtb_start, node, "timebase-frequency", &size);
	if (timebase && (size == 4))
		timebase_period_ns = 1000000000 / *timebase;

	fdt_set_boot_cpuid_phys(_dtb_start, pir_reg);
	fdt_init(_dtb_start);

	serial_console_init();
}
