mirror of
https://mirrors.bfsu.edu.cn/git/linux.git
synced 2024-11-30 15:44:13 +08:00
751605152b
For the sake of consistency, let rename all ctrl_out/in calls to the write/read calls so we have the same API consistent with the other architectures hence open the door for the increasing of the test compilation coverage. The unsigned long coercive cast is removed because all variables are set to the right type "void __iomem *". Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org>
258 lines
5.6 KiB
C
258 lines
5.6 KiB
C
/*
|
|
* linux/arch/h8300/kernel/setup.c
|
|
*
|
|
* Copyright (C) 2001-2014 Yoshinori Sato <ysato@users.sourceforge.jp>
|
|
*/
|
|
|
|
/*
|
|
* This file handles the architecture-dependent parts of system setup
|
|
*/
|
|
|
|
#include <linux/kernel.h>
|
|
#include <linux/sched.h>
|
|
#include <linux/delay.h>
|
|
#include <linux/interrupt.h>
|
|
#include <linux/mm.h>
|
|
#include <linux/fs.h>
|
|
#include <linux/console.h>
|
|
#include <linux/errno.h>
|
|
#include <linux/string.h>
|
|
#include <linux/bootmem.h>
|
|
#include <linux/seq_file.h>
|
|
#include <linux/init.h>
|
|
#include <linux/platform_device.h>
|
|
#include <linux/module.h>
|
|
#include <linux/of.h>
|
|
#include <linux/of_fdt.h>
|
|
#include <linux/of_platform.h>
|
|
#include <linux/of_address.h>
|
|
#include <linux/clk-provider.h>
|
|
#include <linux/memblock.h>
|
|
#include <linux/screen_info.h>
|
|
#include <linux/clocksource.h>
|
|
|
|
#include <asm/setup.h>
|
|
#include <asm/irq.h>
|
|
#include <asm/pgtable.h>
|
|
#include <asm/sections.h>
|
|
#include <asm/page.h>
|
|
|
|
#if defined(CONFIG_CPU_H8300H)
|
|
#define CPU "H8/300H"
|
|
#elif defined(CONFIG_CPU_H8S)
|
|
#define CPU "H8S"
|
|
#else
|
|
#define CPU "Unknown"
|
|
#endif
|
|
|
|
unsigned long memory_start;
|
|
unsigned long memory_end;
|
|
EXPORT_SYMBOL(memory_end);
|
|
static unsigned long freq;
|
|
extern char __dtb_start[];
|
|
|
|
#ifdef CONFIG_VT
|
|
struct screen_info screen_info;
|
|
#endif
|
|
|
|
char __initdata command_line[COMMAND_LINE_SIZE];
|
|
|
|
void sim_console_register(void);
|
|
|
|
void __init h8300_fdt_init(void *fdt, char *bootargs)
|
|
{
|
|
if (!fdt)
|
|
fdt = __dtb_start;
|
|
else
|
|
strcpy(command_line, bootargs);
|
|
|
|
early_init_dt_scan(fdt);
|
|
memblock_allow_resize();
|
|
}
|
|
|
|
static void __init bootmem_init(void)
|
|
{
|
|
int bootmap_size;
|
|
unsigned long ram_start_pfn;
|
|
unsigned long free_ram_start_pfn;
|
|
unsigned long ram_end_pfn;
|
|
struct memblock_region *region;
|
|
|
|
memory_end = memory_start = 0;
|
|
|
|
/* Find main memory where is the kernel */
|
|
for_each_memblock(memory, region) {
|
|
memory_start = region->base;
|
|
memory_end = region->base + region->size;
|
|
}
|
|
|
|
if (!memory_end)
|
|
panic("No memory!");
|
|
|
|
ram_start_pfn = PFN_UP(memory_start);
|
|
/* free_ram_start_pfn is first page after kernel */
|
|
free_ram_start_pfn = PFN_UP(__pa(_end));
|
|
ram_end_pfn = PFN_DOWN(memblock_end_of_DRAM());
|
|
|
|
max_pfn = ram_end_pfn;
|
|
|
|
/*
|
|
* give all the memory to the bootmap allocator, tell it to put the
|
|
* boot mem_map at the start of memory
|
|
*/
|
|
bootmap_size = init_bootmem_node(NODE_DATA(0),
|
|
free_ram_start_pfn,
|
|
0,
|
|
ram_end_pfn);
|
|
/*
|
|
* free the usable memory, we have to make sure we do not free
|
|
* the bootmem bitmap so we then reserve it after freeing it :-)
|
|
*/
|
|
free_bootmem(PFN_PHYS(free_ram_start_pfn),
|
|
(ram_end_pfn - free_ram_start_pfn) << PAGE_SHIFT);
|
|
reserve_bootmem(PFN_PHYS(free_ram_start_pfn), bootmap_size,
|
|
BOOTMEM_DEFAULT);
|
|
|
|
for_each_memblock(reserved, region) {
|
|
reserve_bootmem(region->base, region->size, BOOTMEM_DEFAULT);
|
|
}
|
|
}
|
|
|
|
void __init setup_arch(char **cmdline_p)
|
|
{
|
|
unflatten_and_copy_device_tree();
|
|
|
|
init_mm.start_code = (unsigned long) _stext;
|
|
init_mm.end_code = (unsigned long) _etext;
|
|
init_mm.end_data = (unsigned long) _edata;
|
|
init_mm.brk = (unsigned long) 0;
|
|
|
|
pr_notice("\r\n\nuClinux " CPU "\n");
|
|
pr_notice("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
|
|
|
|
if (*command_line)
|
|
strcpy(boot_command_line, command_line);
|
|
*cmdline_p = boot_command_line;
|
|
|
|
parse_early_param();
|
|
|
|
bootmem_init();
|
|
#if defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)
|
|
sim_console_register();
|
|
#endif
|
|
|
|
early_platform_driver_probe("earlyprintk", 1, 0);
|
|
/*
|
|
* get kmalloc into gear
|
|
*/
|
|
paging_init();
|
|
}
|
|
|
|
/*
|
|
* Get CPU information for use by the procfs.
|
|
*/
|
|
|
|
static int show_cpuinfo(struct seq_file *m, void *v)
|
|
{
|
|
char *cpu;
|
|
|
|
cpu = CPU;
|
|
|
|
seq_printf(m, "CPU:\t\t%s\n"
|
|
"Clock:\t\t%lu.%1luMHz\n"
|
|
"BogoMips:\t%lu.%02lu\n"
|
|
"Calibration:\t%lu loops\n",
|
|
cpu,
|
|
freq/1000, freq%1000,
|
|
(loops_per_jiffy*HZ)/500000,
|
|
((loops_per_jiffy*HZ)/5000)%100,
|
|
(loops_per_jiffy*HZ));
|
|
|
|
return 0;
|
|
}
|
|
|
|
static void *c_start(struct seq_file *m, loff_t *pos)
|
|
{
|
|
return *pos < num_possible_cpus() ?
|
|
((void *) 0x12345678) : 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)
|
|
{
|
|
}
|
|
|
|
const struct seq_operations cpuinfo_op = {
|
|
.start = c_start,
|
|
.next = c_next,
|
|
.stop = c_stop,
|
|
.show = show_cpuinfo,
|
|
};
|
|
|
|
static int __init device_probe(void)
|
|
{
|
|
of_platform_populate(NULL, NULL, NULL, NULL);
|
|
|
|
return 0;
|
|
}
|
|
|
|
device_initcall(device_probe);
|
|
|
|
#if defined(CONFIG_CPU_H8300H)
|
|
#define get_wait(base, addr) ({ \
|
|
int baddr; \
|
|
baddr = ((addr) / 0x200000 * 2); \
|
|
w *= (readw((base) + 2) & (3 << baddr)) + 1; \
|
|
})
|
|
#endif
|
|
#if defined(CONFIG_CPU_H8S)
|
|
#define get_wait(base, addr) ({ \
|
|
int baddr; \
|
|
baddr = ((addr) / 0x200000 * 16); \
|
|
w *= (readl((base) + 2) & (7 << baddr)) + 1; \
|
|
})
|
|
#endif
|
|
|
|
static __init int access_timing(void)
|
|
{
|
|
struct device_node *bsc;
|
|
void __iomem *base;
|
|
unsigned long addr = (unsigned long)&__delay;
|
|
int bit = 1 << (addr / 0x200000);
|
|
int w;
|
|
|
|
bsc = of_find_compatible_node(NULL, NULL, "renesas,h8300-bsc");
|
|
base = of_iomap(bsc, 0);
|
|
w = (readb(base + 0) & bit)?2:1;
|
|
if (readb(base + 1) & bit)
|
|
w *= get_wait(base, addr);
|
|
else
|
|
w *= 2;
|
|
return w * 3 / 2;
|
|
}
|
|
|
|
void __init calibrate_delay(void)
|
|
{
|
|
struct device_node *cpu;
|
|
int freq;
|
|
|
|
cpu = of_find_compatible_node(NULL, NULL, "renesas,h8300");
|
|
of_property_read_s32(cpu, "clock-frequency", &freq);
|
|
loops_per_jiffy = freq / HZ / (access_timing() * 2);
|
|
pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n",
|
|
loops_per_jiffy / (500000 / HZ),
|
|
(loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy);
|
|
}
|
|
|
|
|
|
void __init time_init(void)
|
|
{
|
|
of_clk_init(NULL);
|
|
clocksource_probe();
|
|
}
|