19d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn/*
29d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * OpenRISC setup.c
39d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *
49d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Linux architectural port borrowing liberally from similar works of
59d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * others.  All original copyrights apply as per the original source
69d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * declaration.
79d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *
89d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Modifications for the OpenRISC architecture:
99d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Copyright (C) 2003 Matjaz Breskvar <phoenix@bsemi.com>
109d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Copyright (C) 2010-2011 Jonas Bonn <jonas@southpole.se>
119d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *
129d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *      This program is free software; you can redistribute it and/or
139d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *      modify it under the terms of the GNU General Public License
149d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *      as published by the Free Software Foundation; either version
159d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *      2 of the License, or (at your option) any later version.
169d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *
179d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * This file handles the architecture-dependent parts of initialization
189d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn */
199d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
209d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/errno.h>
219d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/sched.h>
229d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/kernel.h>
239d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/mm.h>
249d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/stddef.h>
259d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/unistd.h>
269d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/ptrace.h>
279d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/slab.h>
289d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/tty.h>
299d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/ioport.h>
309d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/delay.h>
319d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/console.h>
329d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/init.h>
339d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/bootmem.h>
349d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/seq_file.h>
359d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/serial.h>
369d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/initrd.h>
379d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/of_fdt.h>
389d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/of.h>
399d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/memblock.h>
409d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/device.h>
419d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <linux/of_platform.h>
429d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
43be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven#include <asm/sections.h>
449d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/segment.h>
459d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/pgtable.h>
469d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/types.h>
479d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/setup.h>
489d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/io.h>
499d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/cpuinfo.h>
509d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include <asm/delay.h>
519d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
529d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#include "vmlinux.h"
539d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
549d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic unsigned long __init setup_memory(void)
559d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
569d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned long bootmap_size;
579d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned long ram_start_pfn;
589d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned long free_ram_start_pfn;
599d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned long ram_end_pfn;
609d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	phys_addr_t memory_start, memory_end;
619d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	struct memblock_region *region;
629d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
639d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	memory_end = memory_start = 0;
649d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
659d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	/* Find main memory where is the kernel */
669d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	for_each_memblock(memory, region) {
679d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		memory_start = region->base;
689d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		memory_end = region->base + region->size;
699d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "%s: Memory: 0x%x-0x%x\n", __func__,
709d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       memory_start, memory_end);
719d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	}
729d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
739d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (!memory_end) {
749d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		panic("No memory!");
759d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	}
769d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
779d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	ram_start_pfn = PFN_UP(memory_start);
789d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	/* free_ram_start_pfn is first page after kernel */
79be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven	free_ram_start_pfn = PFN_UP(__pa(_end));
809d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	ram_end_pfn = PFN_DOWN(memblock_end_of_DRAM());
819d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
829d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	max_pfn = ram_end_pfn;
839d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
849d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	/*
859d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	 * initialize the boot-time allocator (with low memory only).
869d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	 *
879d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	 * This makes the memory from the end of the kernel to the end of
889d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	 * RAM usable.
899d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	 * init_bootmem sets the global values min_low_pfn, max_low_pfn.
909d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	 */
919d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	bootmap_size = init_bootmem(free_ram_start_pfn,
929d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn				    ram_end_pfn - ram_start_pfn);
939d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	free_bootmem(PFN_PHYS(free_ram_start_pfn),
949d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		     (ram_end_pfn - free_ram_start_pfn) << PAGE_SHIFT);
959d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	reserve_bootmem(PFN_PHYS(free_ram_start_pfn), bootmap_size,
969d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			BOOTMEM_DEFAULT);
979d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
989d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	for_each_memblock(reserved, region) {
999d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "Reserved - 0x%08x-0x%08x\n",
1009d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       (u32) region->base, (u32) region->size);
1019d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		reserve_bootmem(region->base, region->size, BOOTMEM_DEFAULT);
1029d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	}
1039d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1049d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	return ram_end_pfn;
1059d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
1069d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1079d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstruct cpuinfo cpuinfo;
1089d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1099d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic void print_cpuinfo(void)
1109d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
1119d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned long upr = mfspr(SPR_UPR);
1129d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned long vr = mfspr(SPR_VR);
1139d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned int version;
1149d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned int revision;
1159d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1169d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	version = (vr & SPR_VR_VER) >> 24;
1179d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	revision = (vr & SPR_VR_REV);
1189d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1199d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	printk(KERN_INFO "CPU: OpenRISC-%x (revision %d) @%d MHz\n",
1209d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	       version, revision, cpuinfo.clock_frequency / 1000000);
1219d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1229d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (!(upr & SPR_UPR_UP)) {
1239d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO
1249d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       "-- no UPR register... unable to detect configuration\n");
1259d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		return;
1269d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	}
1279d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1289d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & SPR_UPR_DCP)
1299d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO
1309d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       "-- dcache: %4d bytes total, %2d bytes/line, %d way(s)\n",
1319d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       cpuinfo.dcache_size, cpuinfo.dcache_block_size, 1);
1329d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	else
1339d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "-- dcache disabled\n");
1349d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & SPR_UPR_ICP)
1359d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO
1369d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       "-- icache: %4d bytes total, %2d bytes/line, %d way(s)\n",
1379d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       cpuinfo.icache_size, cpuinfo.icache_block_size, 1);
1389d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	else
1399d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "-- icache disabled\n");
1409d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1419d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & SPR_UPR_DMP)
1429d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "-- dmmu: %4d entries, %lu way(s)\n",
1439d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2),
1449d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       1 + (mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTW));
1459d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & SPR_UPR_IMP)
1469d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "-- immu: %4d entries, %lu way(s)\n",
1479d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       1 << ((mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTS) >> 2),
1489d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       1 + (mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTW));
1499d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1509d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	printk(KERN_INFO "-- additional features:\n");
1519d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & SPR_UPR_DUP)
1529d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "-- debug unit\n");
1539d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & SPR_UPR_PCUP)
1549d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "-- performance counters\n");
1559d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & SPR_UPR_PMP)
1569d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "-- power management\n");
1579d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & SPR_UPR_PICP)
1589d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "-- PIC\n");
1599d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & SPR_UPR_TTP)
1609d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "-- timer\n");
1619d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & SPR_UPR_CUP)
1629d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_INFO "-- custom unit(s)\n");
1639d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
1649d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1659d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnvoid __init setup_cpuinfo(void)
1669d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
1679d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	struct device_node *cpu;
1689d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned long iccfgr, dccfgr;
1699d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned long cache_set_size, cache_ways;
1709d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1719d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	cpu = of_find_compatible_node(NULL, NULL, "opencores,or1200-rtlsvn481");
1729d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (!cpu)
1739d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		panic("No compatible CPU found in device tree...\n");
1749d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1759d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	iccfgr = mfspr(SPR_ICCFGR);
1769d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	cache_ways = 1 << (iccfgr & SPR_ICCFGR_NCW);
1779d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	cache_set_size = 1 << ((iccfgr & SPR_ICCFGR_NCS) >> 3);
1789d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	cpuinfo.icache_block_size = 16 << ((iccfgr & SPR_ICCFGR_CBS) >> 7);
1799d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	cpuinfo.icache_size =
1809d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	    cache_set_size * cache_ways * cpuinfo.icache_block_size;
1819d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1829d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	dccfgr = mfspr(SPR_DCCFGR);
1839d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	cache_ways = 1 << (dccfgr & SPR_DCCFGR_NCW);
1849d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	cache_set_size = 1 << ((dccfgr & SPR_DCCFGR_NCS) >> 3);
1859d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	cpuinfo.dcache_block_size = 16 << ((dccfgr & SPR_DCCFGR_CBS) >> 7);
1869d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	cpuinfo.dcache_size =
1879d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	    cache_set_size * cache_ways * cpuinfo.dcache_block_size;
1889d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1899d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (of_property_read_u32(cpu, "clock-frequency",
1909d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn				 &cpuinfo.clock_frequency)) {
1919d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk(KERN_WARNING
1929d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       "Device tree missing CPU 'clock-frequency' parameter."
1939d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       "Assuming frequency 25MHZ"
1949d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		       "This is probably not what you want.");
1959d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	}
1969d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1979d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	of_node_put(cpu);
1989d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
1999d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	print_cpuinfo();
2009d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
2019d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2029d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn/**
2039d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * or32_early_setup
2049d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *
2059d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Handles the pointer to the device tree that this kernel is to use
2069d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * for establishing the available platform devices.
2079d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *
208dec830189e1e192a80f574243a2dc31bdc1c4fc5Stefan Kristiansson * Falls back on built-in device tree in case null pointer is passed.
2099d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn */
2109d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
211621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoevenvoid __init or32_early_setup(void *fdt)
2129d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
213621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven	if (fdt)
214621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven		pr_info("FDT at %p\n", fdt);
215621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven	else {
216621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven		fdt = __dtb_start;
217621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven		pr_info("Compiled-in FDT at %p\n", fdt);
218dec830189e1e192a80f574243a2dc31bdc1c4fc5Stefan Kristiansson	}
219621c2cd853fca98258b720d9fe7e8c031ec7f96fGeert Uytterhoeven	early_init_devtree(fdt);
2209d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
2219d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2229d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic int __init openrisc_device_probe(void)
2239d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
2249d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	of_platform_populate(NULL, NULL, NULL, NULL);
2259d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2269d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	return 0;
2279d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
2289d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2299d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonndevice_initcall(openrisc_device_probe);
2309d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2319d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic inline unsigned long extract_value_bits(unsigned long reg,
2329d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn					       short bit_nr, short width)
2339d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
2349d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	return (reg >> bit_nr) & (0 << width);
2359d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
2369d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2379d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic inline unsigned long extract_value(unsigned long reg, unsigned long mask)
2389d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
2399d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	while (!(mask & 0x1)) {
2409d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		reg = reg >> 1;
2419d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		mask = mask >> 1;
2429d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	}
2439d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	return mask & reg;
2449d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
2459d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2469d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnvoid __init detect_unit_config(unsigned long upr, unsigned long mask,
2479d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			       char *text, void (*func) (void))
2489d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
2499d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (text != NULL)
2509d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk("%s", text);
2519d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2529d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (upr & mask) {
2539d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		if (func != NULL)
2549d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			func();
2559d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		else
2569d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			printk("present\n");
2579d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	} else
2589d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		printk("not present\n");
2599d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
2609d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2619d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn/*
2629d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * calibrate_delay
2639d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *
2649d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * Lightweight calibrate_delay implementation that calculates loops_per_jiffy
2659d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn * from the clock frequency passed in via the device tree
2669d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn *
2679d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn */
2689d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2698e8550ef01676829f4d4b175a1ce4fee30f7a778Paul Gortmakervoid calibrate_delay(void)
2709d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
2719d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	const int *val;
2729d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	struct device_node *cpu = NULL;
2739d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	cpu = of_find_compatible_node(NULL, NULL, "opencores,or1200-rtlsvn481");
2749d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	val = of_get_property(cpu, "clock-frequency", NULL);
2759d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (!val)
2769d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		panic("no cpu 'clock-frequency' parameter in device tree");
2779d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	loops_per_jiffy = *val / HZ;
2789d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n",
2799d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		loops_per_jiffy / (500000 / HZ),
2809d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		(loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy);
2819d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
2829d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2839d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnvoid __init setup_arch(char **cmdline_p)
2849d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
2859d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned long max_low_pfn;
2869d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2873486892f998fea5b4f1a0a4d093f09b7d0024696Rob Herring	unflatten_and_copy_device_tree();
2889d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2899d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	setup_cpuinfo();
2909d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2919d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	/* process 1's initial memory region is the kernel code/data */
292be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven	init_mm.start_code = (unsigned long)_stext;
293be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven	init_mm.end_code = (unsigned long)_etext;
294be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven	init_mm.end_data = (unsigned long)_edata;
295be5940c9fd2fa1905fab4353bb9c7051d088d824Geert Uytterhoeven	init_mm.brk = (unsigned long)_end;
2969d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
2979d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#ifdef CONFIG_BLK_DEV_INITRD
2989d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	initrd_start = (unsigned long)&__initrd_start;
2999d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	initrd_end = (unsigned long)&__initrd_end;
3009d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (initrd_start == initrd_end) {
3019d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		initrd_start = 0;
3029d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		initrd_end = 0;
3039d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	}
3049d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	initrd_below_start_ok = 1;
3059d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#endif
3069d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3079d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	/* setup bootmem allocator */
3089d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	max_low_pfn = setup_memory();
3099d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3109d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	/* paging_init() sets up the MMU and marks all pages as reserved */
3119d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	paging_init();
3129d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3139d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#if defined(CONFIG_VT) && defined(CONFIG_DUMMY_CONSOLE)
3149d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	if (!conswitchp)
3159d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn		conswitchp = &dummy_con;
3169d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn#endif
3179d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
318bbf28b505ac2dd923b9051ca5031cf87bf7c40ccRob Herring	*cmdline_p = boot_command_line;
3199d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3209d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	printk(KERN_INFO "OpenRISC Linux -- http://openrisc.net\n");
3219d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
3229d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3239d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic int show_cpuinfo(struct seq_file *m, void *v)
3249d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
3259d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	unsigned long vr;
3269d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	int version, revision;
3279d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3289d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	vr = mfspr(SPR_VR);
3299d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	version = (vr & SPR_VR_VER) >> 24;
3309d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	revision = vr & SPR_VR_REV;
3319d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3329d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	return seq_printf(m,
3339d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  "cpu\t\t: OpenRISC-%x\n"
3349d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  "revision\t: %d\n"
3359d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  "frequency\t: %ld\n"
3369d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  "dcache size\t: %d bytes\n"
3379d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  "dcache block size\t: %d bytes\n"
3389d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  "icache size\t: %d bytes\n"
3399d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  "icache block size\t: %d bytes\n"
3409d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  "immu\t\t: %d entries, %lu ways\n"
3419d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  "dmmu\t\t: %d entries, %lu ways\n"
3429d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  "bogomips\t: %lu.%02lu\n",
3439d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  version,
3449d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  revision,
3459d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  loops_per_jiffy * HZ,
3469d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  cpuinfo.dcache_size,
3479d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  cpuinfo.dcache_block_size,
3489d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  cpuinfo.icache_size,
3499d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  cpuinfo.icache_block_size,
3509d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  1 << ((mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTS) >> 2),
3519d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  1 + (mfspr(SPR_DMMUCFGR) & SPR_DMMUCFGR_NTW),
3529d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  1 << ((mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTS) >> 2),
3539d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  1 + (mfspr(SPR_IMMUCFGR) & SPR_IMMUCFGR_NTW),
3549d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  (loops_per_jiffy * HZ) / 500000,
3559d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn			  ((loops_per_jiffy * HZ) / 5000) % 100);
3569d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
3579d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3589d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic void *c_start(struct seq_file *m, loff_t * pos)
3599d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
3609d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	/* We only have one CPU... */
3619d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	return *pos < 1 ? (void *)1 : NULL;
3629d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
3639d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3649d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic void *c_next(struct seq_file *m, void *v, loff_t * pos)
3659d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
3669d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	++*pos;
3679d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	return NULL;
3689d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
3699d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3709d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnstatic void c_stop(struct seq_file *m, void *v)
3719d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn{
3729d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn}
3739d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn
3749d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonnconst struct seq_operations cpuinfo_op = {
3759d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	.start = c_start,
3769d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	.next = c_next,
3779d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	.stop = c_stop,
3789d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn	.show = show_cpuinfo,
3799d02a4283e9ce4e9ca11ff00615bdacdb0515a1aJonas Bonn};
380