/*
 * Copyright (C) 2004-2006 Atmel Corporation
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License version 2 as
 * published by the Free Software Foundation.
 */

#include <linux/clk.h>
#include <linux/init.h>
#include <linux/sched.h>
#include <linux/console.h>
#include <linux/ioport.h>
#include <linux/bootmem.h>
#include <linux/fs.h>
#include <linux/module.h>
#include <linux/root_dev.h>
#include <linux/cpu.h>
#include <linux/kernel.h>

#include <asm/sections.h>
#include <asm/processor.h>
#include <asm/pgtable.h>
#include <asm/setup.h>
#include <asm/sysreg.h>

#include <asm/arch/board.h>
#include <asm/arch/init.h>

extern int root_mountflags;

/*
 * Bootloader-provided information about physical memory
 */
struct tag_mem_range *mem_phys;
struct tag_mem_range *mem_reserved;
struct tag_mem_range *mem_ramdisk;

/*
 * Initialize loops_per_jiffy as 5000000 (500MIPS).
 * Better make it too large than too small...
 */
struct avr32_cpuinfo boot_cpu_data = {
	.loops_per_jiffy = 5000000
};
EXPORT_SYMBOL(boot_cpu_data);

static char __initdata command_line[COMMAND_LINE_SIZE];

/*
 * Should be more than enough, but if you have a _really_ complex
 * setup, you might need to increase the size of this...
 */
static struct tag_mem_range __initdata mem_range_cache[32];
static unsigned mem_range_next_free;

/*
 * Standard memory resources
 */
static struct resource mem_res[] = {
	{
		.name	= "Kernel code",
		.start	= 0,
		.end	= 0,
		.flags	= IORESOURCE_MEM
	},
	{
		.name	= "Kernel data",
		.start	= 0,
		.end	= 0,
		.flags	= IORESOURCE_MEM,
	},
};

#define kernel_code	mem_res[0]
#define kernel_data	mem_res[1]

/*
 * Early framebuffer allocation. Works as follows:
 *   - If fbmem_size is zero, nothing will be allocated or reserved.
 *   - If fbmem_start is zero when setup_bootmem() is called,
 *     fbmem_size bytes will be allocated from the bootmem allocator.
 *   - If fbmem_start is nonzero, an area of size fbmem_size will be
 *     reserved at the physical address fbmem_start if necessary. If
 *     the area isn't in a memory region known to the kernel, it will
 *     be left alone.
 *
 * Board-specific code may use these variables to set up platform data
 * for the framebuffer driver if fbmem_size is nonzero.
 */
static unsigned long __initdata fbmem_start;
static unsigned long __initdata fbmem_size;

/*
 * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for
 * use as framebuffer.
 *
 * "fbmem=xxx[kKmM]@yyy[kKmM]" defines a memory region of size xxx and
 * starting at yyy to be reserved for use as framebuffer.
 *
 * The kernel won't verify that the memory region starting at yyy
 * actually contains usable RAM.
 */
static int __init early_parse_fbmem(char *p)
{
	fbmem_size = memparse(p, &p);
	if (*p == '@')
		fbmem_start = memparse(p, &p);
	return 0;
}
early_param("fbmem", early_parse_fbmem);

static inline void __init resource_init(void)
{
	struct tag_mem_range *region;

	kernel_code.start = __pa(init_mm.start_code);
	kernel_code.end = __pa(init_mm.end_code - 1);
	kernel_data.start = __pa(init_mm.end_code);
	kernel_data.end = __pa(init_mm.brk - 1);

	for (region = mem_phys; region; region = region->next) {
		struct resource *res;
		unsigned long phys_start, phys_end;

		if (region->size == 0)
			continue;

		phys_start = region->addr;
		phys_end = phys_start + region->size - 1;

		res = alloc_bootmem_low(sizeof(*res));
		res->name = "System RAM";
		res->start = phys_start;
		res->end = phys_end;
		res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;

		request_resource (&iomem_resource, res);

		if (kernel_code.start >= res->start &&
		    kernel_code.end <= res->end)
			request_resource (res, &kernel_code);
		if (kernel_data.start >= res->start &&
		    kernel_data.end <= res->end)
			request_resource (res, &kernel_data);
	}
}

static int __init parse_tag_core(struct tag *tag)
{
	if (tag->hdr.size > 2) {
		if ((tag->u.core.flags & 1) == 0)
			root_mountflags &= ~MS_RDONLY;
		ROOT_DEV = new_decode_dev(tag->u.core.rootdev);
	}
	return 0;
}
__tagtable(ATAG_CORE, parse_tag_core);

static int __init parse_tag_mem_range(struct tag *tag,
				      struct tag_mem_range **root)
{
	struct tag_mem_range *cur, **pprev;
	struct tag_mem_range *new;

	/*
	 * Ignore zero-sized entries. If we're running standalone, the
	 * SDRAM code may emit such entries if something goes
	 * wrong...
	 */
	if (tag->u.mem_range.size == 0)
		return 0;

	/*
	 * Copy the data so the bootmem init code doesn't need to care
	 * about it.
	 */
	if (mem_range_next_free >= ARRAY_SIZE(mem_range_cache))
		panic("Physical memory map too complex!\n");

	new = &mem_range_cache[mem_range_next_free++];
	*new = tag->u.mem_range;

	pprev = root;
	cur = *root;
	while (cur) {
		pprev = &cur->next;
		cur = cur->next;
	}

	*pprev = new;
	new->next = NULL;

	return 0;
}

static int __init parse_tag_mem(struct tag *tag)
{
	return parse_tag_mem_range(tag, &mem_phys);
}
__tagtable(ATAG_MEM, parse_tag_mem);

static int __init parse_tag_cmdline(struct tag *tag)
{
	strlcpy(boot_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
	return 0;
}
__tagtable(ATAG_CMDLINE, parse_tag_cmdline);

static int __init parse_tag_rdimg(struct tag *tag)
{
	return parse_tag_mem_range(tag, &mem_ramdisk);
}
__tagtable(ATAG_RDIMG, parse_tag_rdimg);

static int __init parse_tag_clock(struct tag *tag)
{
	/*
	 * We'll figure out the clocks by peeking at the system
	 * manager regs directly.
	 */
	return 0;
}
__tagtable(ATAG_CLOCK, parse_tag_clock);

static int __init parse_tag_rsvd_mem(struct tag *tag)
{
	return parse_tag_mem_range(tag, &mem_reserved);
}
__tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem);

/*
 * Scan the tag table for this tag, and call its parse function. The
 * tag table is built by the linker from all the __tagtable
 * declarations.
 */
static int __init parse_tag(struct tag *tag)
{
	extern struct tagtable __tagtable_begin, __tagtable_end;
	struct tagtable *t;

	for (t = &__tagtable_begin; t < &__tagtable_end; t++)
		if (tag->hdr.tag == t->tag) {
			t->parse(tag);
			break;
		}

	return t < &__tagtable_end;
}

/*
 * Parse all tags in the list we got from the boot loader
 */
static void __init parse_tags(struct tag *t)
{
	for (; t->hdr.tag != ATAG_NONE; t = tag_next(t))
		if (!parse_tag(t))
			printk(KERN_WARNING
			       "Ignoring unrecognised tag 0x%08x\n",
			       t->hdr.tag);
}

void __init setup_arch (char **cmdline_p)
{
	struct clk *cpu_clk;

	parse_tags(bootloader_tags);

	setup_processor();
	setup_platform();
	setup_board();

	cpu_clk = clk_get(NULL, "cpu");
	if (IS_ERR(cpu_clk)) {
		printk(KERN_WARNING "Warning: Unable to get CPU clock\n");
	} else {
		unsigned long cpu_hz = clk_get_rate(cpu_clk);

		/*
		 * Well, duh, but it's probably a good idea to
		 * increment the use count.
		 */
		clk_enable(cpu_clk);

		boot_cpu_data.clk = cpu_clk;
		boot_cpu_data.loops_per_jiffy = cpu_hz * 4;
		printk("CPU: Running at %lu.%03lu MHz\n",
		       ((cpu_hz + 500) / 1000) / 1000,
		       ((cpu_hz + 500) / 1000) % 1000);
	}

	init_mm.start_code = (unsigned long) &_text;
	init_mm.end_code = (unsigned long) &_etext;
	init_mm.end_data = (unsigned long) &_edata;
	init_mm.brk = (unsigned long) &_end;

	strlcpy(command_line, boot_command_line, COMMAND_LINE_SIZE);
	*cmdline_p = command_line;
	parse_early_param();

	setup_bootmem();

	board_setup_fbmem(fbmem_start, fbmem_size);

#ifdef CONFIG_VT
	conswitchp = &dummy_con;
#endif

	paging_init();

	resource_init();
}
