/*
 * 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 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(saved_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, saved_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();
}
