/* 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, 1,
				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,
};
