Merge tag 'cpuinit-v4.1-rc8' of git://git.kernel.org/pub/scm/linux/kernel/git/paulg...
[linux-2.6-block.git] / arch / h8300 / kernel / setup.c
CommitLineData
d8b0bdb4
YS
1/*
2 * linux/arch/h8300/kernel/setup.c
3 *
4 * Copyright (C) 2001-2014 Yoshinori Sato <ysato@users.sourceforge.jp>
5 */
6
7/*
8 * This file handles the architecture-dependent parts of system setup
9 */
10
11#include <linux/kernel.h>
12#include <linux/sched.h>
13#include <linux/delay.h>
14#include <linux/interrupt.h>
15#include <linux/mm.h>
16#include <linux/fs.h>
17#include <linux/console.h>
18#include <linux/errno.h>
19#include <linux/string.h>
20#include <linux/bootmem.h>
21#include <linux/seq_file.h>
22#include <linux/init.h>
23#include <linux/platform_device.h>
24#include <linux/module.h>
25#include <linux/of.h>
26#include <linux/of_fdt.h>
27#include <linux/of_platform.h>
28#include <linux/of_address.h>
29#include <linux/clk-provider.h>
30#include <linux/memblock.h>
31#include <linux/screen_info.h>
32
33#include <asm/setup.h>
34#include <asm/irq.h>
35#include <asm/pgtable.h>
36#include <asm/sections.h>
37#include <asm/page.h>
38
39#if defined(CONFIG_CPU_H8300H)
40#define CPU "H8/300H"
41#elif defined(CONFIG_CPU_H8S)
42#define CPU "H8S"
43#else
44#define CPU "Unknown"
45#endif
46
47unsigned long memory_start;
48unsigned long memory_end;
49EXPORT_SYMBOL(memory_end);
50static unsigned long freq;
51extern char __dtb_start[];
52
53#ifdef CONFIG_VT
54struct screen_info screen_info;
55#endif
56
57char __initdata command_line[COMMAND_LINE_SIZE];
58
59void sim_console_register(void);
60
61void __init h8300_fdt_init(void *fdt, char *bootargs)
62{
63 if (!fdt)
64 fdt = __dtb_start;
65 else
66 strcpy(command_line, bootargs);
67
68 early_init_dt_scan(fdt);
69 memblock_allow_resize();
70}
71
72static void __init bootmem_init(void)
73{
74 int bootmap_size;
75 unsigned long ram_start_pfn;
76 unsigned long free_ram_start_pfn;
77 unsigned long ram_end_pfn;
78 struct memblock_region *region;
79
80 memory_end = memory_start = 0;
81
82 /* Find main memory where is the kernel */
83 for_each_memblock(memory, region) {
84 memory_start = region->base;
85 memory_end = region->base + region->size;
86 }
87
88 if (!memory_end)
89 panic("No memory!");
90
91 ram_start_pfn = PFN_UP(memory_start);
92 /* free_ram_start_pfn is first page after kernel */
93 free_ram_start_pfn = PFN_UP(__pa(_end));
94 ram_end_pfn = PFN_DOWN(memblock_end_of_DRAM());
95
96 max_pfn = ram_end_pfn;
97
98 /*
99 * give all the memory to the bootmap allocator, tell it to put the
100 * boot mem_map at the start of memory
101 */
102 bootmap_size = init_bootmem_node(NODE_DATA(0),
103 free_ram_start_pfn,
104 0,
105 ram_end_pfn);
106 /*
107 * free the usable memory, we have to make sure we do not free
108 * the bootmem bitmap so we then reserve it after freeing it :-)
109 */
110 free_bootmem(PFN_PHYS(free_ram_start_pfn),
111 (ram_end_pfn - free_ram_start_pfn) << PAGE_SHIFT);
112 reserve_bootmem(PFN_PHYS(free_ram_start_pfn), bootmap_size,
113 BOOTMEM_DEFAULT);
114
115 for_each_memblock(reserved, region) {
116 reserve_bootmem(region->base, region->size, BOOTMEM_DEFAULT);
117 }
118}
119
120void __init setup_arch(char **cmdline_p)
121{
122 unflatten_and_copy_device_tree();
123
124 init_mm.start_code = (unsigned long) _stext;
125 init_mm.end_code = (unsigned long) _etext;
126 init_mm.end_data = (unsigned long) _edata;
127 init_mm.brk = (unsigned long) 0;
128
129 pr_notice("\r\n\nuClinux " CPU "\n");
130 pr_notice("Flat model support (C) 1998,1999 Kenneth Albanowski, D. Jeff Dionne\n");
131
132 if (*command_line)
133 strcpy(boot_command_line, command_line);
134 *cmdline_p = boot_command_line;
135
136 parse_early_param();
137
138 bootmem_init();
139#if defined(CONFIG_H8300H_SIM) || defined(CONFIG_H8S_SIM)
140 sim_console_register();
141#endif
142
143 early_platform_driver_probe("earlyprintk", 1, 0);
144 /*
145 * get kmalloc into gear
146 */
147 paging_init();
148}
149
150/*
151 * Get CPU information for use by the procfs.
152 */
153
154static int show_cpuinfo(struct seq_file *m, void *v)
155{
156 char *cpu;
157
158 cpu = CPU;
159
160 seq_printf(m, "CPU:\t\t%s\n"
161 "Clock:\t\t%lu.%1luMHz\n"
162 "BogoMips:\t%lu.%02lu\n"
163 "Calibration:\t%lu loops\n",
164 cpu,
165 freq/1000, freq%1000,
166 (loops_per_jiffy*HZ)/500000,
167 ((loops_per_jiffy*HZ)/5000)%100,
168 (loops_per_jiffy*HZ));
169
170 return 0;
171}
172
173static void *c_start(struct seq_file *m, loff_t *pos)
174{
175 return *pos < num_possible_cpus() ?
176 ((void *) 0x12345678) : NULL;
177}
178
179static void *c_next(struct seq_file *m, void *v, loff_t *pos)
180{
181 ++*pos;
182 return c_start(m, pos);
183}
184
185static void c_stop(struct seq_file *m, void *v)
186{
187}
188
189const struct seq_operations cpuinfo_op = {
190 .start = c_start,
191 .next = c_next,
192 .stop = c_stop,
193 .show = show_cpuinfo,
194};
195
196static int __init device_probe(void)
197{
198 of_platform_populate(NULL, NULL, NULL, NULL);
199
200 return 0;
201}
202
203device_initcall(device_probe);
204
205#if defined(CONFIG_CPU_H8300H)
206#define get_wait(base, addr) ({ \
207 int baddr; \
208 baddr = ((addr) / 0x200000 * 2); \
209 w *= (ctrl_inw((unsigned long)(base) + 2) & (3 << baddr)) + 1; \
210 })
211#endif
212#if defined(CONFIG_CPU_H8S)
213#define get_wait(base, addr) ({ \
214 int baddr; \
215 baddr = ((addr) / 0x200000 * 16); \
216 w *= (ctrl_inl((unsigned long)(base) + 2) & (7 << baddr)) + 1; \
217 })
218#endif
219
220static __init int access_timing(void)
221{
222 struct device_node *bsc;
223 void __iomem *base;
224 unsigned long addr = (unsigned long)&__delay;
225 int bit = 1 << (addr / 0x200000);
226 int w;
227
228 bsc = of_find_compatible_node(NULL, NULL, "renesas,h8300-bsc");
229 base = of_iomap(bsc, 0);
230 w = (ctrl_inb((unsigned long)base + 0) & bit)?2:1;
231 if (ctrl_inb((unsigned long)base + 1) & bit)
232 w *= get_wait(base, addr);
233 else
234 w *= 2;
235 return w * 3 / 2;
236}
237
238void __init calibrate_delay(void)
239{
240 struct device_node *cpu;
241 int freq;
242
243 cpu = of_find_compatible_node(NULL, NULL, "renesas,h8300");
244 of_property_read_s32(cpu, "clock-frequency", &freq);
245 loops_per_jiffy = freq / HZ / (access_timing() * 2);
246 pr_cont("%lu.%02lu BogoMIPS (lpj=%lu)\n",
247 loops_per_jiffy / (500000 / HZ),
248 (loops_per_jiffy / (5000 / HZ)) % 100, loops_per_jiffy);
249}
250
251
252void __init time_init(void)
253{
254 of_clk_init(NULL);
255}