/* MN10300 Arch-specific initialisation
 *
 * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved.
 * Written by David Howells (dhowells@redhat.com)
 *
 * This program is free software; you can redistribute it and/or
 * modify it under the terms of the GNU General Public Licence
 * as published by the Free Software Foundation; either version
 * 2 of the Licence, or (at your option) any later version.
 */
#include <linux/errno.h>
#include <linux/sched.h>
#include <linux/kernel.h>
#include <linux/mm.h>
#include <linux/stddef.h>
#include <linux/unistd.h>
#include <linux/ptrace.h>
#include <linux/slab.h>
#include <linux/user.h>
#include <linux/tty.h>
#include <linux/ioport.h>
#include <linux/delay.h>
#include <linux/init.h>
#include <linux/bootmem.h>
#include <linux/seq_file.h>
#include <asm/processor.h>
#include <linux/console.h>
#include <asm/uaccess.h>
#include <asm/system.h>
#include <asm/setup.h>
#include <asm/io.h>
#include <asm/smp.h>
#include <asm/proc/proc.h>
#include <asm/busctl-regs.h>
#include <asm/fpu.h>
#include <asm/sections.h>

struct mn10300_cpuinfo boot_cpu_data;

/* For PCI or other memory-mapped resources */
unsigned long pci_mem_start = 0x18000000;

char redboot_command_line[COMMAND_LINE_SIZE] =
	"console=ttyS0,115200 root=/dev/mtdblock3 rw";

char __initdata redboot_platform_name[COMMAND_LINE_SIZE];

static struct resource code_resource = {
	.start	= 0x100000,
	.end	= 0,
	.name	= "Kernel code",
};

static struct resource data_resource = {
	.start	= 0,
	.end	= 0,
	.name	= "Kernel data",
};

static unsigned long __initdata phys_memory_base;
static unsigned long __initdata phys_memory_end;
static unsigned long __initdata memory_end;
unsigned long memory_size;

struct thread_info *__current_ti = &init_thread_union.thread_info;
struct task_struct *__current = &init_task;

#define mn10300_known_cpus 3
static const char *const mn10300_cputypes[] = {
	"am33v1",
	"am33v2",
	"am34v1",
	"unknown"
};

/*
 *
 */
static void __init parse_mem_cmdline(char **cmdline_p)
{
	char *from, *to, c;

	/* save unparsed command line copy for /proc/cmdline */
	strcpy(boot_command_line, redboot_command_line);

	/* see if there's an explicit memory size option */
	from = redboot_command_line;
	to = redboot_command_line;
	c = ' ';

	for (;;) {
		if (c == ' ' && !memcmp(from, "mem=", 4)) {
			if (to != redboot_command_line)
				to--;
			memory_size = memparse(from + 4, &from);
		}

		c = *(from++);
		if (!c)
			break;

		*(to++) = c;
	}

	*to = '\0';
	*cmdline_p = redboot_command_line;

	if (memory_size == 0)
		panic("Memory size not known\n");

	memory_end = (unsigned long) CONFIG_KERNEL_RAM_BASE_ADDRESS +
		memory_size;
	if (memory_end > phys_memory_end)
		memory_end = phys_memory_end;
}

/*
 * architecture specific setup
 */
void __init setup_arch(char **cmdline_p)
{
	unsigned long bootmap_size;
	unsigned long kstart_pfn, start_pfn, free_pfn, end_pfn;

	cpu_init();
	unit_setup();
	parse_mem_cmdline(cmdline_p);

	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;

	code_resource.start = virt_to_bus(&_text);
	code_resource.end = virt_to_bus(&_etext)-1;
	data_resource.start = virt_to_bus(&_etext);
	data_resource.end = virt_to_bus(&_edata)-1;

#define PFN_UP(x)	(((x) + PAGE_SIZE-1) >> PAGE_SHIFT)
#define PFN_DOWN(x)	((x) >> PAGE_SHIFT)
#define PFN_PHYS(x)	((x) << PAGE_SHIFT)

	start_pfn = (CONFIG_KERNEL_RAM_BASE_ADDRESS >> PAGE_SHIFT);
	kstart_pfn = PFN_UP(__pa(&_text));
	free_pfn = PFN_UP(__pa(&_end));
	end_pfn = PFN_DOWN(__pa(memory_end));

	bootmap_size = init_bootmem_node(&contig_page_data,
					 free_pfn,
					 start_pfn,
					 end_pfn);

	if (kstart_pfn > start_pfn)
		free_bootmem(PFN_PHYS(start_pfn),
			     PFN_PHYS(kstart_pfn - start_pfn));

	free_bootmem(PFN_PHYS(free_pfn),
		     PFN_PHYS(end_pfn - free_pfn));

	/* If interrupt vector table is in main ram, then we need to
	   reserve the page it is occupying. */
	if (CONFIG_INTERRUPT_VECTOR_BASE >= CONFIG_KERNEL_RAM_BASE_ADDRESS &&
	    CONFIG_INTERRUPT_VECTOR_BASE < memory_end)
		reserve_bootmem(CONFIG_INTERRUPT_VECTOR_BASE, PAGE_SIZE,
				BOOTMEM_DEFAULT);

	reserve_bootmem(PAGE_ALIGN(PFN_PHYS(free_pfn)), bootmap_size,
			BOOTMEM_DEFAULT);

#ifdef CONFIG_VT
#if defined(CONFIG_VGA_CONSOLE)
	conswitchp = &vga_con;
#elif defined(CONFIG_DUMMY_CONSOLE)
	conswitchp = &dummy_con;
#endif
#endif

	paging_init();
}

/*
 * perform CPU initialisation
 */
void __init cpu_init(void)
{
	unsigned long cpurev = CPUREV, type;
	unsigned long base, size;

	type = (CPUREV & CPUREV_TYPE) >> CPUREV_TYPE_S;
	if (type > mn10300_known_cpus)
		type = mn10300_known_cpus;

	printk(KERN_INFO "Matsushita %s, rev %ld\n",
	       mn10300_cputypes[type],
	       (cpurev & CPUREV_REVISION) >> CPUREV_REVISION_S);

	/* determine the memory size and base from the memory controller regs */
	memory_size = 0;

	base = SDBASE(0);
	if (base & SDBASE_CE) {
		size = (base & SDBASE_CBAM) << SDBASE_CBAM_SHIFT;
		size = ~size + 1;
		base &= SDBASE_CBA;

		printk(KERN_INFO "SDRAM[0]: %luMb @%08lx\n", size >> 20, base);
		memory_size += size;
		phys_memory_base = base;
	}

	base = SDBASE(1);
	if (base & SDBASE_CE) {
		size = (base & SDBASE_CBAM) << SDBASE_CBAM_SHIFT;
		size = ~size + 1;
		base &= SDBASE_CBA;

		printk(KERN_INFO "SDRAM[1]: %luMb @%08lx\n", size >> 20, base);
		memory_size += size;
		if (phys_memory_base == 0)
			phys_memory_base = base;
	}

	phys_memory_end = phys_memory_base + memory_size;

#ifdef CONFIG_FPU
	fpu_init_state();
#endif
}

/*
 * Get CPU information for use by the procfs.
 */
static int show_cpuinfo(struct seq_file *m, void *v)
{
	unsigned long cpurev = CPUREV, type, icachesz, dcachesz;

	type = (CPUREV & CPUREV_TYPE) >> CPUREV_TYPE_S;
	if (type > mn10300_known_cpus)
		type = mn10300_known_cpus;

	icachesz =
		((cpurev & CPUREV_ICWAY ) >> CPUREV_ICWAY_S)  *
		((cpurev & CPUREV_ICSIZE) >> CPUREV_ICSIZE_S) *
		1024;

	dcachesz =
		((cpurev & CPUREV_DCWAY ) >> CPUREV_DCWAY_S)  *
		((cpurev & CPUREV_DCSIZE) >> CPUREV_DCSIZE_S) *
		1024;

	seq_printf(m,
		   "processor  : 0\n"
		   "vendor_id  : Matsushita\n"
		   "cpu core   : %s\n"
		   "cpu rev    : %lu\n"
		   "model name : " PROCESSOR_MODEL_NAME		"\n"
		   "icache size: %lu\n"
		   "dcache size: %lu\n",
		   mn10300_cputypes[type],
		   (cpurev & CPUREV_REVISION) >> CPUREV_REVISION_S,
		   icachesz,
		   dcachesz
		   );

	seq_printf(m,
		   "ioclk speed: %lu.%02luMHz\n"
		   "bogomips   : %lu.%02lu\n\n",
		   MN10300_IOCLK / 1000000,
		   (MN10300_IOCLK / 10000) % 100,
		   loops_per_jiffy / (500000 / HZ),
		   (loops_per_jiffy / (5000 / HZ)) % 100
		   );

	return 0;
}

static void *c_start(struct seq_file *m, loff_t *pos)
{
	return *pos < NR_CPUS ? cpu_data + *pos : NULL;
}

static void *c_next(struct seq_file *m, void *v, loff_t *pos)
{
	++*pos;
	return c_start(m, pos);
}

static void c_stop(struct seq_file *m, void *v)
{
}

struct seq_operations cpuinfo_op = {
	.start	= c_start,
	.next	= c_next,
	.stop	= c_stop,
	.show	= show_cpuinfo,
};
