2 * Copyright (C) 2004-2006 Atmel Corporation
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License version 2 as
6 * published by the Free Software Foundation.
10 #include <linux/init.h>
11 #include <linux/sched.h>
12 #include <linux/console.h>
13 #include <linux/ioport.h>
14 #include <linux/bootmem.h>
16 #include <linux/module.h>
17 #include <linux/root_dev.h>
18 #include <linux/cpu.h>
20 #include <asm/sections.h>
21 #include <asm/processor.h>
22 #include <asm/pgtable.h>
23 #include <asm/setup.h>
24 #include <asm/sysreg.h>
26 #include <asm/arch/board.h>
27 #include <asm/arch/init.h>
29 extern int root_mountflags
;
32 * Bootloader-provided information about physical memory
34 struct tag_mem_range
*mem_phys
;
35 struct tag_mem_range
*mem_reserved
;
36 struct tag_mem_range
*mem_ramdisk
;
39 * Initialize loops_per_jiffy as 5000000 (500MIPS).
40 * Better make it too large than too small...
42 struct avr32_cpuinfo boot_cpu_data
= {
43 .loops_per_jiffy
= 5000000
45 EXPORT_SYMBOL(boot_cpu_data
);
47 static char command_line
[COMMAND_LINE_SIZE
];
50 * Should be more than enough, but if you have a _really_ complex
51 * setup, you might need to increase the size of this...
53 static struct tag_mem_range __initdata mem_range_cache
[32];
54 static unsigned mem_range_next_free
;
57 * Standard memory resources
59 static struct resource mem_res
[] = {
61 .name
= "Kernel code",
64 .flags
= IORESOURCE_MEM
67 .name
= "Kernel data",
70 .flags
= IORESOURCE_MEM
,
74 #define kernel_code mem_res[0]
75 #define kernel_data mem_res[1]
78 * Early framebuffer allocation. Works as follows:
79 * - If fbmem_size is zero, nothing will be allocated or reserved.
80 * - If fbmem_start is zero when setup_bootmem() is called,
81 * fbmem_size bytes will be allocated from the bootmem allocator.
82 * - If fbmem_start is nonzero, an area of size fbmem_size will be
83 * reserved at the physical address fbmem_start if necessary. If
84 * the area isn't in a memory region known to the kernel, it will
87 * Board-specific code may use these variables to set up platform data
88 * for the framebuffer driver if fbmem_size is nonzero.
90 static unsigned long __initdata fbmem_start
;
91 static unsigned long __initdata fbmem_size
;
94 * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for
97 * "fbmem=xxx[kKmM]@yyy[kKmM]" defines a memory region of size xxx and
98 * starting at yyy to be reserved for use as framebuffer.
100 * The kernel won't verify that the memory region starting at yyy
101 * actually contains usable RAM.
103 static int __init
early_parse_fbmem(char *p
)
105 fbmem_size
= memparse(p
, &p
);
107 fbmem_start
= memparse(p
, &p
);
110 early_param("fbmem", early_parse_fbmem
);
112 static inline void __init
resource_init(void)
114 struct tag_mem_range
*region
;
116 kernel_code
.start
= __pa(init_mm
.start_code
);
117 kernel_code
.end
= __pa(init_mm
.end_code
- 1);
118 kernel_data
.start
= __pa(init_mm
.end_code
);
119 kernel_data
.end
= __pa(init_mm
.brk
- 1);
121 for (region
= mem_phys
; region
; region
= region
->next
) {
122 struct resource
*res
;
123 unsigned long phys_start
, phys_end
;
125 if (region
->size
== 0)
128 phys_start
= region
->addr
;
129 phys_end
= phys_start
+ region
->size
- 1;
131 res
= alloc_bootmem_low(sizeof(*res
));
132 res
->name
= "System RAM";
133 res
->start
= phys_start
;
135 res
->flags
= IORESOURCE_MEM
| IORESOURCE_BUSY
;
137 request_resource (&iomem_resource
, res
);
139 if (kernel_code
.start
>= res
->start
&&
140 kernel_code
.end
<= res
->end
)
141 request_resource (res
, &kernel_code
);
142 if (kernel_data
.start
>= res
->start
&&
143 kernel_data
.end
<= res
->end
)
144 request_resource (res
, &kernel_data
);
148 static int __init
parse_tag_core(struct tag
*tag
)
150 if (tag
->hdr
.size
> 2) {
151 if ((tag
->u
.core
.flags
& 1) == 0)
152 root_mountflags
&= ~MS_RDONLY
;
153 ROOT_DEV
= new_decode_dev(tag
->u
.core
.rootdev
);
157 __tagtable(ATAG_CORE
, parse_tag_core
);
159 static int __init
parse_tag_mem_range(struct tag
*tag
,
160 struct tag_mem_range
**root
)
162 struct tag_mem_range
*cur
, **pprev
;
163 struct tag_mem_range
*new;
166 * Ignore zero-sized entries. If we're running standalone, the
167 * SDRAM code may emit such entries if something goes
170 if (tag
->u
.mem_range
.size
== 0)
174 * Copy the data so the bootmem init code doesn't need to care
177 if (mem_range_next_free
>=
178 (sizeof(mem_range_cache
) / sizeof(mem_range_cache
[0])))
179 panic("Physical memory map too complex!\n");
181 new = &mem_range_cache
[mem_range_next_free
++];
182 *new = tag
->u
.mem_range
;
197 static int __init
parse_tag_mem(struct tag
*tag
)
199 return parse_tag_mem_range(tag
, &mem_phys
);
201 __tagtable(ATAG_MEM
, parse_tag_mem
);
203 static int __init
parse_tag_cmdline(struct tag
*tag
)
205 strlcpy(saved_command_line
, tag
->u
.cmdline
.cmdline
, COMMAND_LINE_SIZE
);
208 __tagtable(ATAG_CMDLINE
, parse_tag_cmdline
);
210 static int __init
parse_tag_rdimg(struct tag
*tag
)
212 return parse_tag_mem_range(tag
, &mem_ramdisk
);
214 __tagtable(ATAG_RDIMG
, parse_tag_rdimg
);
216 static int __init
parse_tag_clock(struct tag
*tag
)
219 * We'll figure out the clocks by peeking at the system
220 * manager regs directly.
224 __tagtable(ATAG_CLOCK
, parse_tag_clock
);
226 static int __init
parse_tag_rsvd_mem(struct tag
*tag
)
228 return parse_tag_mem_range(tag
, &mem_reserved
);
230 __tagtable(ATAG_RSVD_MEM
, parse_tag_rsvd_mem
);
233 * Scan the tag table for this tag, and call its parse function. The
234 * tag table is built by the linker from all the __tagtable
237 static int __init
parse_tag(struct tag
*tag
)
239 extern struct tagtable __tagtable_begin
, __tagtable_end
;
242 for (t
= &__tagtable_begin
; t
< &__tagtable_end
; t
++)
243 if (tag
->hdr
.tag
== t
->tag
) {
248 return t
< &__tagtable_end
;
252 * Parse all tags in the list we got from the boot loader
254 static void __init
parse_tags(struct tag
*t
)
256 for (; t
->hdr
.tag
!= ATAG_NONE
; t
= tag_next(t
))
259 "Ignoring unrecognised tag 0x%08x\n",
263 void __init
setup_arch (char **cmdline_p
)
267 parse_tags(bootloader_tags
);
273 cpu_clk
= clk_get(NULL
, "cpu");
274 if (IS_ERR(cpu_clk
)) {
275 printk(KERN_WARNING
"Warning: Unable to get CPU clock\n");
277 unsigned long cpu_hz
= clk_get_rate(cpu_clk
);
280 * Well, duh, but it's probably a good idea to
281 * increment the use count.
285 boot_cpu_data
.clk
= cpu_clk
;
286 boot_cpu_data
.loops_per_jiffy
= cpu_hz
* 4;
287 printk("CPU: Running at %lu.%03lu MHz\n",
288 ((cpu_hz
+ 500) / 1000) / 1000,
289 ((cpu_hz
+ 500) / 1000) % 1000);
292 init_mm
.start_code
= (unsigned long) &_text
;
293 init_mm
.end_code
= (unsigned long) &_etext
;
294 init_mm
.end_data
= (unsigned long) &_edata
;
295 init_mm
.brk
= (unsigned long) &_end
;
297 strlcpy(command_line
, saved_command_line
, COMMAND_LINE_SIZE
);
298 *cmdline_p
= command_line
;
303 board_setup_fbmem(fbmem_start
, fbmem_size
);
306 conswitchp
= &dummy_con
;