setup.c 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336
  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 <asm/sections.h>
  19. #include <asm/processor.h>
  20. #include <asm/pgtable.h>
  21. #include <asm/setup.h>
  22. #include <asm/sysreg.h>
  23. #include <asm/arch/board.h>
  24. #include <asm/arch/init.h>
  25. extern int root_mountflags;
  26. /*
  27. * Bootloader-provided information about physical memory
  28. */
  29. struct tag_mem_range *mem_phys;
  30. struct tag_mem_range *mem_reserved;
  31. struct tag_mem_range *mem_ramdisk;
  32. /*
  33. * Initialize loops_per_jiffy as 5000000 (500MIPS).
  34. * Better make it too large than too small...
  35. */
  36. struct avr32_cpuinfo boot_cpu_data = {
  37. .loops_per_jiffy = 5000000
  38. };
  39. EXPORT_SYMBOL(boot_cpu_data);
  40. static char command_line[COMMAND_LINE_SIZE];
  41. /*
  42. * Should be more than enough, but if you have a _really_ complex
  43. * setup, you might need to increase the size of this...
  44. */
  45. static struct tag_mem_range __initdata mem_range_cache[32];
  46. static unsigned mem_range_next_free;
  47. /*
  48. * Standard memory resources
  49. */
  50. static struct resource mem_res[] = {
  51. {
  52. .name = "Kernel code",
  53. .start = 0,
  54. .end = 0,
  55. .flags = IORESOURCE_MEM
  56. },
  57. {
  58. .name = "Kernel data",
  59. .start = 0,
  60. .end = 0,
  61. .flags = IORESOURCE_MEM,
  62. },
  63. };
  64. #define kernel_code mem_res[0]
  65. #define kernel_data mem_res[1]
  66. /*
  67. * Early framebuffer allocation. Works as follows:
  68. * - If fbmem_size is zero, nothing will be allocated or reserved.
  69. * - If fbmem_start is zero when setup_bootmem() is called,
  70. * fbmem_size bytes will be allocated from the bootmem allocator.
  71. * - If fbmem_start is nonzero, an area of size fbmem_size will be
  72. * reserved at the physical address fbmem_start if necessary. If
  73. * the area isn't in a memory region known to the kernel, it will
  74. * be left alone.
  75. *
  76. * Board-specific code may use these variables to set up platform data
  77. * for the framebuffer driver if fbmem_size is nonzero.
  78. */
  79. static unsigned long __initdata fbmem_start;
  80. static unsigned long __initdata fbmem_size;
  81. /*
  82. * "fbmem=xxx[kKmM]" allocates the specified amount of boot memory for
  83. * use as framebuffer.
  84. *
  85. * "fbmem=xxx[kKmM]@yyy[kKmM]" defines a memory region of size xxx and
  86. * starting at yyy to be reserved for use as framebuffer.
  87. *
  88. * The kernel won't verify that the memory region starting at yyy
  89. * actually contains usable RAM.
  90. */
  91. static int __init early_parse_fbmem(char *p)
  92. {
  93. fbmem_size = memparse(p, &p);
  94. if (*p == '@')
  95. fbmem_start = memparse(p, &p);
  96. return 0;
  97. }
  98. early_param("fbmem", early_parse_fbmem);
  99. static inline void __init resource_init(void)
  100. {
  101. struct tag_mem_range *region;
  102. kernel_code.start = __pa(init_mm.start_code);
  103. kernel_code.end = __pa(init_mm.end_code - 1);
  104. kernel_data.start = __pa(init_mm.end_code);
  105. kernel_data.end = __pa(init_mm.brk - 1);
  106. for (region = mem_phys; region; region = region->next) {
  107. struct resource *res;
  108. unsigned long phys_start, phys_end;
  109. if (region->size == 0)
  110. continue;
  111. phys_start = region->addr;
  112. phys_end = phys_start + region->size - 1;
  113. res = alloc_bootmem_low(sizeof(*res));
  114. res->name = "System RAM";
  115. res->start = phys_start;
  116. res->end = phys_end;
  117. res->flags = IORESOURCE_MEM | IORESOURCE_BUSY;
  118. request_resource (&iomem_resource, res);
  119. if (kernel_code.start >= res->start &&
  120. kernel_code.end <= res->end)
  121. request_resource (res, &kernel_code);
  122. if (kernel_data.start >= res->start &&
  123. kernel_data.end <= res->end)
  124. request_resource (res, &kernel_data);
  125. }
  126. }
  127. static int __init parse_tag_core(struct tag *tag)
  128. {
  129. if (tag->hdr.size > 2) {
  130. if ((tag->u.core.flags & 1) == 0)
  131. root_mountflags &= ~MS_RDONLY;
  132. ROOT_DEV = new_decode_dev(tag->u.core.rootdev);
  133. }
  134. return 0;
  135. }
  136. __tagtable(ATAG_CORE, parse_tag_core);
  137. static int __init parse_tag_mem_range(struct tag *tag,
  138. struct tag_mem_range **root)
  139. {
  140. struct tag_mem_range *cur, **pprev;
  141. struct tag_mem_range *new;
  142. /*
  143. * Ignore zero-sized entries. If we're running standalone, the
  144. * SDRAM code may emit such entries if something goes
  145. * wrong...
  146. */
  147. if (tag->u.mem_range.size == 0)
  148. return 0;
  149. /*
  150. * Copy the data so the bootmem init code doesn't need to care
  151. * about it.
  152. */
  153. if (mem_range_next_free >=
  154. (sizeof(mem_range_cache) / sizeof(mem_range_cache[0])))
  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. static int __init parse_tag_ethernet(struct tag *tag)
  199. {
  200. #if 0
  201. const struct platform_device *pdev;
  202. /*
  203. * We really need a bus type that supports "classes"...this
  204. * will do for now (until we must handle other kinds of
  205. * ethernet controllers)
  206. */
  207. pdev = platform_get_device("macb", tag->u.ethernet.mac_index);
  208. if (pdev && pdev->dev.platform_data) {
  209. struct eth_platform_data *data = pdev->dev.platform_data;
  210. data->valid = 1;
  211. data->mii_phy_addr = tag->u.ethernet.mii_phy_addr;
  212. memcpy(data->hw_addr, tag->u.ethernet.hw_address,
  213. sizeof(data->hw_addr));
  214. }
  215. #endif
  216. return 0;
  217. }
  218. __tagtable(ATAG_ETHERNET, parse_tag_ethernet);
  219. /*
  220. * Scan the tag table for this tag, and call its parse function. The
  221. * tag table is built by the linker from all the __tagtable
  222. * declarations.
  223. */
  224. static int __init parse_tag(struct tag *tag)
  225. {
  226. extern struct tagtable __tagtable_begin, __tagtable_end;
  227. struct tagtable *t;
  228. for (t = &__tagtable_begin; t < &__tagtable_end; t++)
  229. if (tag->hdr.tag == t->tag) {
  230. t->parse(tag);
  231. break;
  232. }
  233. return t < &__tagtable_end;
  234. }
  235. /*
  236. * Parse all tags in the list we got from the boot loader
  237. */
  238. static void __init parse_tags(struct tag *t)
  239. {
  240. for (; t->hdr.tag != ATAG_NONE; t = tag_next(t))
  241. if (!parse_tag(t))
  242. printk(KERN_WARNING
  243. "Ignoring unrecognised tag 0x%08x\n",
  244. t->hdr.tag);
  245. }
  246. void __init setup_arch (char **cmdline_p)
  247. {
  248. struct clk *cpu_clk;
  249. parse_tags(bootloader_tags);
  250. setup_processor();
  251. setup_platform();
  252. setup_board();
  253. cpu_clk = clk_get(NULL, "cpu");
  254. if (IS_ERR(cpu_clk)) {
  255. printk(KERN_WARNING "Warning: Unable to get CPU clock\n");
  256. } else {
  257. unsigned long cpu_hz = clk_get_rate(cpu_clk);
  258. /*
  259. * Well, duh, but it's probably a good idea to
  260. * increment the use count.
  261. */
  262. clk_enable(cpu_clk);
  263. boot_cpu_data.clk = cpu_clk;
  264. boot_cpu_data.loops_per_jiffy = cpu_hz * 4;
  265. printk("CPU: Running at %lu.%03lu MHz\n",
  266. ((cpu_hz + 500) / 1000) / 1000,
  267. ((cpu_hz + 500) / 1000) % 1000);
  268. }
  269. init_mm.start_code = (unsigned long) &_text;
  270. init_mm.end_code = (unsigned long) &_etext;
  271. init_mm.end_data = (unsigned long) &_edata;
  272. init_mm.brk = (unsigned long) &_end;
  273. strlcpy(command_line, saved_command_line, COMMAND_LINE_SIZE);
  274. *cmdline_p = command_line;
  275. parse_early_param();
  276. setup_bootmem();
  277. board_setup_fbmem(fbmem_start, fbmem_size);
  278. #ifdef CONFIG_VT
  279. conswitchp = &dummy_con;
  280. #endif
  281. paging_init();
  282. resource_init();
  283. }