setup.c 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312
  1. /*
  2. * Copyright (C) 2004-2006 Atmel Corporation
  3. *
  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.
  7. */
  8. #include <linux/clk.h>
  9. #include <linux/init.h>
  10. #include <linux/sched.h>
  11. #include <linux/console.h>
  12. #include <linux/ioport.h>
  13. #include <linux/bootmem.h>
  14. #include <linux/fs.h>
  15. #include <linux/module.h>
  16. #include <linux/root_dev.h>
  17. #include <linux/cpu.h>
  18. #include <linux/kernel.h>
  19. #include <asm/sections.h>
  20. #include <asm/processor.h>
  21. #include <asm/pgtable.h>
  22. #include <asm/setup.h>
  23. #include <asm/sysreg.h>
  24. #include <asm/arch/board.h>
  25. #include <asm/arch/init.h>
  26. extern int root_mountflags;
  27. /*
  28. * Bootloader-provided information about physical memory
  29. */
  30. struct tag_mem_range *mem_phys;
  31. struct tag_mem_range *mem_reserved;
  32. struct tag_mem_range *mem_ramdisk;
  33. /*
  34. * Initialize loops_per_jiffy as 5000000 (500MIPS).
  35. * Better make it too large than too small...
  36. */
  37. struct avr32_cpuinfo boot_cpu_data = {
  38. .loops_per_jiffy = 5000000
  39. };
  40. EXPORT_SYMBOL(boot_cpu_data);
  41. static char command_line[COMMAND_LINE_SIZE];
  42. /*
  43. * Should be more than enough, but if you have a _really_ complex
  44. * setup, you might need to increase the size of this...
  45. */
  46. static struct tag_mem_range __initdata mem_range_cache[32];
  47. static unsigned mem_range_next_free;
  48. /*
  49. * Standard memory resources
  50. */
  51. static struct resource mem_res[] = {
  52. {
  53. .name = "Kernel code",
  54. .start = 0,
  55. .end = 0,
  56. .flags = IORESOURCE_MEM
  57. },
  58. {
  59. .name = "Kernel data",
  60. .start = 0,
  61. .end = 0,
  62. .flags = IORESOURCE_MEM,
  63. },
  64. };
  65. #define kernel_code mem_res[0]
  66. #define kernel_data mem_res[1]
  67. /*
  68. * Early framebuffer allocation. Works as follows:
  69. * - If fbmem_size is zero, nothing will be allocated or reserved.
  70. * - If fbmem_start is zero when setup_bootmem() is called,
  71. * fbmem_size bytes will be allocated from the bootmem allocator.
  72. * - If fbmem_start is nonzero, an area of size fbmem_size will be
  73. * reserved at the physical address fbmem_start if necessary. If
  74. * the area isn't in a memory region known to the kernel, it will
  75. * be left alone.
  76. *
  77. * Board-specific code may use these variables to set up platform data
  78. * for the framebuffer driver if fbmem_size is nonzero.
  79. */
  80. static unsigned long __initdata fbmem_start;
  81. static unsigned long __initdata fbmem_size;
  82. /*
  83. * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for
  84. * use as framebuffer.
  85. *
  86. * "fbmem=xxx[kKmM]@yyy[kKmM]" defines a memory region of size xxx and
  87. * starting at yyy to be reserved for use as framebuffer.
  88. *
  89. * The kernel won't verify that the memory region starting at yyy
  90. * actually contains usable RAM.
  91. */
  92. static int __init early_parse_fbmem(char *p)
  93. {
  94. fbmem_size = memparse(p, &p);
  95. if (*p == '@')
  96. fbmem_start = memparse(p, &p);
  97. return 0;
  98. }
  99. early_param("fbmem", early_parse_fbmem);
  100. static inline void __init resource_init(void)
  101. {
  102. struct tag_mem_range *region;
  103. kernel_code.start = __pa(init_mm.start_code);
  104. kernel_code.end = __pa(init_mm.end_code - 1);
  105. kernel_data.start = __pa(init_mm.end_code);
  106. kernel_data.end = __pa(init_mm.brk - 1);
  107. for (region = mem_phys; region; region = region->next) {
  108. struct resource *res;
  109. unsigned long phys_start, phys_end;
  110. if (region->size == 0)
  111. continue;
  112. phys_start = region->addr;
  113. phys_end = phys_start + region->size - 1;
  114. res = alloc_bootmem_low(sizeof(*res));
  115. res->name = "System RAM";
  116. res->start = phys_start;
  117. res->end = phys_end;
  118. res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
  119. request_resource (&iomem_resource, res);
  120. if (kernel_code.start >= res->start &&
  121. kernel_code.end <= res->end)
  122. request_resource (res, &kernel_code);
  123. if (kernel_data.start >= res->start &&
  124. kernel_data.end <= res->end)
  125. request_resource (res, &kernel_data);
  126. }
  127. }
  128. static int __init parse_tag_core(struct tag *tag)
  129. {
  130. if (tag->hdr.size > 2) {
  131. if ((tag->u.core.flags & 1) == 0)
  132. root_mountflags &= ~MS_RDONLY;
  133. ROOT_DEV = new_decode_dev(tag->u.core.rootdev);
  134. }
  135. return 0;
  136. }
  137. __tagtable(ATAG_CORE, parse_tag_core);
  138. static int __init parse_tag_mem_range(struct tag *tag,
  139. struct tag_mem_range **root)
  140. {
  141. struct tag_mem_range *cur, **pprev;
  142. struct tag_mem_range *new;
  143. /*
  144. * Ignore zero-sized entries. If we're running standalone, the
  145. * SDRAM code may emit such entries if something goes
  146. * wrong...
  147. */
  148. if (tag->u.mem_range.size == 0)
  149. return 0;
  150. /*
  151. * Copy the data so the bootmem init code doesn't need to care
  152. * about it.
  153. */
  154. if (mem_range_next_free >= ARRAY_SIZE(mem_range_cache))
  155. panic("Physical memory map too complex!\n");
  156. new = &mem_range_cache[mem_range_next_free++];
  157. *new = tag->u.mem_range;
  158. pprev = root;
  159. cur = *root;
  160. while (cur) {
  161. pprev = &cur->next;
  162. cur = cur->next;
  163. }
  164. *pprev = new;
  165. new->next = NULL;
  166. return 0;
  167. }
  168. static int __init parse_tag_mem(struct tag *tag)
  169. {
  170. return parse_tag_mem_range(tag, &mem_phys);
  171. }
  172. __tagtable(ATAG_MEM, parse_tag_mem);
  173. static int __init parse_tag_cmdline(struct tag *tag)
  174. {
  175. strlcpy(saved_command_line, tag->u.cmdline.cmdline, COMMAND_LINE_SIZE);
  176. return 0;
  177. }
  178. __tagtable(ATAG_CMDLINE, parse_tag_cmdline);
  179. static int __init parse_tag_rdimg(struct tag *tag)
  180. {
  181. return parse_tag_mem_range(tag, &mem_ramdisk);
  182. }
  183. __tagtable(ATAG_RDIMG, parse_tag_rdimg);
  184. static int __init parse_tag_clock(struct tag *tag)
  185. {
  186. /*
  187. * We'll figure out the clocks by peeking at the system
  188. * manager regs directly.
  189. */
  190. return 0;
  191. }
  192. __tagtable(ATAG_CLOCK, parse_tag_clock);
  193. static int __init parse_tag_rsvd_mem(struct tag *tag)
  194. {
  195. return parse_tag_mem_range(tag, &mem_reserved);
  196. }
  197. __tagtable(ATAG_RSVD_MEM, parse_tag_rsvd_mem);
  198. /*
  199. * Scan the tag table for this tag, and call its parse function. The
  200. * tag table is built by the linker from all the __tagtable
  201. * declarations.
  202. */
  203. static int __init parse_tag(struct tag *tag)
  204. {
  205. extern struct tagtable __tagtable_begin, __tagtable_end;
  206. struct tagtable *t;
  207. for (t = &__tagtable_begin; t < &__tagtable_end; t++)
  208. if (tag->hdr.tag == t->tag) {
  209. t->parse(tag);
  210. break;
  211. }
  212. return t < &__tagtable_end;
  213. }
  214. /*
  215. * Parse all tags in the list we got from the boot loader
  216. */
  217. static void __init parse_tags(struct tag *t)
  218. {
  219. for (; t->hdr.tag != ATAG_NONE; t = tag_next(t))
  220. if (!parse_tag(t))
  221. printk(KERN_WARNING
  222. "Ignoring unrecognised tag 0x%08x\n",
  223. t->hdr.tag);
  224. }
  225. void __init setup_arch (char **cmdline_p)
  226. {
  227. struct clk *cpu_clk;
  228. parse_tags(bootloader_tags);
  229. setup_processor();
  230. setup_platform();
  231. setup_board();
  232. cpu_clk = clk_get(NULL, "cpu");
  233. if (IS_ERR(cpu_clk)) {
  234. printk(KERN_WARNING "Warning: Unable to get CPU clock\n");
  235. } else {
  236. unsigned long cpu_hz = clk_get_rate(cpu_clk);
  237. /*
  238. * Well, duh, but it's probably a good idea to
  239. * increment the use count.
  240. */
  241. clk_enable(cpu_clk);
  242. boot_cpu_data.clk = cpu_clk;
  243. boot_cpu_data.loops_per_jiffy = cpu_hz * 4;
  244. printk("CPU: Running at %lu.%03lu MHz\n",
  245. ((cpu_hz + 500) / 1000) / 1000,
  246. ((cpu_hz + 500) / 1000) % 1000);
  247. }
  248. init_mm.start_code = (unsigned long) &_text;
  249. init_mm.end_code = (unsigned long) &_etext;
  250. init_mm.end_data = (unsigned long) &_edata;
  251. init_mm.brk = (unsigned long) &_end;
  252. strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE);
  253. *cmdline_p = command_line;
  254. parse_early_param();
  255. setup_bootmem();
  256. board_setup_fbmem(fbmem_start, fbmem_size);
  257. #ifdef CONFIG_VT
  258. conswitchp = &dummy_con;
  259. #endif
  260. paging_init();
  261. resource_init();
  262. }