cpu.c 9.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414
  1. /*
  2. * U-boot - cpu.c CPU specific functions
  3. *
  4. * Copyright (c) 2005-2008 Analog Devices Inc.
  5. *
  6. * (C) Copyright 2000-2004
  7. * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
  8. *
  9. * Licensed under the GPL-2 or later.
  10. */
  11. #include <common.h>
  12. #include <command.h>
  13. #include <serial.h>
  14. #include <version.h>
  15. #include <i2c.h>
  16. #include <asm/blackfin.h>
  17. #include <asm/cplb.h>
  18. #include <asm/clock.h>
  19. #include <asm/mach-common/bits/core.h>
  20. #include <asm/mach-common/bits/ebiu.h>
  21. #include <asm/mach-common/bits/trace.h>
  22. #include "cpu.h"
  23. #include "initcode.h"
  24. ulong bfin_poweron_retx;
  25. DECLARE_GLOBAL_DATA_PTR;
  26. #if defined(CONFIG_CORE1_RUN) && defined(COREB_L1_CODE_START)
  27. void bfin_core1_start(void)
  28. {
  29. #ifdef BF561_FAMILY
  30. /* Enable core 1 */
  31. bfin_write_SYSCR(bfin_read_SYSCR() & ~0x0020);
  32. #else
  33. /* Enable core 1 */
  34. bfin_write32(RCU0_SVECT1, COREB_L1_CODE_START);
  35. bfin_write32(RCU0_CRCTL, 0);
  36. bfin_write32(RCU0_CRCTL, 0x2);
  37. /* Check if core 1 starts */
  38. while (!(bfin_read32(RCU0_CRSTAT) & 0x2))
  39. continue;
  40. bfin_write32(RCU0_CRCTL, 0);
  41. /* flag to notify cces core 1 application */
  42. bfin_write32(SDU0_MSG_SET, (1 << 19));
  43. #endif
  44. }
  45. #endif
  46. __attribute__((always_inline))
  47. static inline void serial_early_puts(const char *s)
  48. {
  49. #ifdef CONFIG_DEBUG_EARLY_SERIAL
  50. serial_puts("Early: ");
  51. serial_puts(s);
  52. #endif
  53. }
  54. static int global_board_data_init(void)
  55. {
  56. #ifndef CONFIG_SYS_GBL_DATA_ADDR
  57. # define CONFIG_SYS_GBL_DATA_ADDR 0
  58. #endif
  59. #ifndef CONFIG_SYS_BD_INFO_ADDR
  60. # define CONFIG_SYS_BD_INFO_ADDR 0
  61. #endif
  62. bd_t *bd;
  63. if (CONFIG_SYS_GBL_DATA_ADDR) {
  64. gd = (gd_t *)(CONFIG_SYS_GBL_DATA_ADDR);
  65. memset((void *)gd, 0, GENERATED_GBL_DATA_SIZE);
  66. } else {
  67. static gd_t _bfin_gd;
  68. gd = &_bfin_gd;
  69. }
  70. if (CONFIG_SYS_BD_INFO_ADDR) {
  71. bd = (bd_t *)(CONFIG_SYS_BD_INFO_ADDR);
  72. memset(bd, 0, GENERATED_BD_INFO_SIZE);
  73. } else {
  74. static bd_t _bfin_bd;
  75. bd = &_bfin_bd;
  76. }
  77. gd->bd = bd;
  78. bd->bi_r_version = version_string;
  79. bd->bi_cpu = __stringify(CONFIG_BFIN_CPU);
  80. bd->bi_board_name = CONFIG_SYS_BOARD;
  81. bd->bi_vco = get_vco();
  82. bd->bi_cclk = get_cclk();
  83. bd->bi_sclk = get_sclk();
  84. bd->bi_memstart = CONFIG_SYS_SDRAM_BASE;
  85. bd->bi_memsize = CONFIG_SYS_MAX_RAM_SIZE;
  86. gd->ram_size = CONFIG_SYS_MAX_RAM_SIZE;
  87. return 0;
  88. }
  89. static void display_global_data(void)
  90. {
  91. bd_t *bd;
  92. #ifndef CONFIG_DEBUG_EARLY_SERIAL
  93. return;
  94. #endif
  95. bd = gd->bd;
  96. printf(" gd: %p\n", gd);
  97. printf(" |-flags: %lx\n", gd->flags);
  98. printf(" |-board_type: %lx\n", gd->arch.board_type);
  99. printf(" |-baudrate: %u\n", gd->baudrate);
  100. printf(" |-have_console: %lx\n", gd->have_console);
  101. printf(" |-ram_size: %lx\n", gd->ram_size);
  102. printf(" |-env_addr: %lx\n", gd->env_addr);
  103. printf(" |-env_valid: %lx\n", gd->env_valid);
  104. printf(" |-jt(%p): %p\n", gd->jt, *(gd->jt));
  105. printf(" \\-bd: %p\n", gd->bd);
  106. printf(" |-bi_boot_params: %lx\n", bd->bi_boot_params);
  107. printf(" |-bi_memstart: %lx\n", bd->bi_memstart);
  108. printf(" |-bi_memsize: %lx\n", bd->bi_memsize);
  109. printf(" |-bi_flashstart: %lx\n", bd->bi_flashstart);
  110. printf(" |-bi_flashsize: %lx\n", bd->bi_flashsize);
  111. printf(" \\-bi_flashoffset: %lx\n", bd->bi_flashoffset);
  112. }
  113. #define CPLB_PAGE_SIZE (4 * 1024 * 1024)
  114. #define CPLB_PAGE_MASK (~(CPLB_PAGE_SIZE - 1))
  115. #if defined(__ADSPBF60x__)
  116. #define CPLB_EX_PAGE_SIZE (16 * 1024 * 1024)
  117. #define CPLB_EX_PAGE_MASK (~(CPLB_EX_PAGE_SIZE - 1))
  118. #else
  119. #define CPLB_EX_PAGE_SIZE CPLB_PAGE_SIZE
  120. #define CPLB_EX_PAGE_MASK CPLB_PAGE_MASK
  121. #endif
  122. void init_cplbtables(void)
  123. {
  124. uint32_t *ICPLB_ADDR, *ICPLB_DATA;
  125. uint32_t *DCPLB_ADDR, *DCPLB_DATA;
  126. uint32_t extern_memory;
  127. size_t i;
  128. void icplb_add(uint32_t addr, uint32_t data)
  129. {
  130. bfin_write32(ICPLB_ADDR + i, addr);
  131. bfin_write32(ICPLB_DATA + i, data);
  132. }
  133. void dcplb_add(uint32_t addr, uint32_t data)
  134. {
  135. bfin_write32(DCPLB_ADDR + i, addr);
  136. bfin_write32(DCPLB_DATA + i, data);
  137. }
  138. /* populate a few common entries ... we'll let
  139. * the memory map and cplb exception handler do
  140. * the rest of the work.
  141. */
  142. i = 0;
  143. ICPLB_ADDR = (uint32_t *)ICPLB_ADDR0;
  144. ICPLB_DATA = (uint32_t *)ICPLB_DATA0;
  145. DCPLB_ADDR = (uint32_t *)DCPLB_ADDR0;
  146. DCPLB_DATA = (uint32_t *)DCPLB_DATA0;
  147. icplb_add(0xFFA00000, L1_IMEMORY);
  148. dcplb_add(0xFF800000, L1_DMEMORY);
  149. ++i;
  150. #if defined(__ADSPBF60x__)
  151. icplb_add(0x0, 0x0);
  152. dcplb_add(CONFIG_SYS_FLASH_BASE, PAGE_SIZE_16MB | CPLB_DIRTY |
  153. CPLB_SUPV_WR | CPLB_USER_WR | CPLB_USER_RD | CPLB_VALID);
  154. ++i;
  155. #endif
  156. if (CONFIG_MEM_SIZE) {
  157. uint32_t mbase = CONFIG_SYS_MONITOR_BASE;
  158. uint32_t mend = mbase + CONFIG_SYS_MONITOR_LEN - 1;
  159. mbase &= CPLB_PAGE_MASK;
  160. mend &= CPLB_PAGE_MASK;
  161. icplb_add(mbase, SDRAM_IKERNEL);
  162. dcplb_add(mbase, SDRAM_DKERNEL);
  163. ++i;
  164. /*
  165. * If the monitor crosses a 4 meg boundary, we'll need
  166. * to lock two entries for it. We assume it doesn't
  167. * cross two 4 meg boundaries ...
  168. */
  169. if (mbase != mend) {
  170. icplb_add(mend, SDRAM_IKERNEL);
  171. dcplb_add(mend, SDRAM_DKERNEL);
  172. ++i;
  173. }
  174. }
  175. #ifndef __ADSPBF60x__
  176. icplb_add(0x20000000, SDRAM_INON_CHBL);
  177. dcplb_add(0x20000000, SDRAM_EBIU);
  178. ++i;
  179. #endif
  180. /* Add entries for the rest of external RAM up to the bootrom */
  181. extern_memory = 0;
  182. #ifdef CONFIG_DEBUG_NULL_PTR
  183. icplb_add(extern_memory,
  184. (SDRAM_IKERNEL & ~PAGE_SIZE_MASK) | PAGE_SIZE_1KB);
  185. dcplb_add(extern_memory,
  186. (SDRAM_DKERNEL & ~PAGE_SIZE_MASK) | PAGE_SIZE_1KB);
  187. ++i;
  188. icplb_add(extern_memory, SDRAM_IKERNEL);
  189. dcplb_add(extern_memory, SDRAM_DKERNEL);
  190. extern_memory += CPLB_PAGE_SIZE;
  191. ++i;
  192. #endif
  193. while (i < 16 && extern_memory <
  194. (CONFIG_SYS_MONITOR_BASE & CPLB_EX_PAGE_MASK)) {
  195. icplb_add(extern_memory, SDRAM_IGENERIC);
  196. dcplb_add(extern_memory, SDRAM_DGENERIC);
  197. extern_memory += CPLB_EX_PAGE_SIZE;
  198. ++i;
  199. }
  200. while (i < 16) {
  201. icplb_add(0, 0);
  202. dcplb_add(0, 0);
  203. ++i;
  204. }
  205. }
  206. int print_cpuinfo(void)
  207. {
  208. char buf[32];
  209. printf("CPU: ADSP %s (Detected Rev: 0.%d) (%s boot)\n",
  210. gd->bd->bi_cpu,
  211. bfin_revid(),
  212. get_bfin_boot_mode(CONFIG_BFIN_BOOT_MODE));
  213. printf("Clock: VCO: %s MHz, ", strmhz(buf, get_vco()));
  214. printf("Core: %s MHz, ", strmhz(buf, get_cclk()));
  215. #if defined(__ADSPBF60x__)
  216. printf("System0: %s MHz, ", strmhz(buf, get_sclk0()));
  217. printf("System1: %s MHz, ", strmhz(buf, get_sclk1()));
  218. printf("Dclk: %s MHz\n", strmhz(buf, get_dclk()));
  219. #else
  220. printf("System: %s MHz\n", strmhz(buf, get_sclk()));
  221. #endif
  222. return 0;
  223. }
  224. int exception_init(void)
  225. {
  226. bfin_write_EVT3(trap);
  227. return 0;
  228. }
  229. int irq_init(void)
  230. {
  231. #ifdef SIC_IMASK0
  232. bfin_write_SIC_IMASK0(0);
  233. bfin_write_SIC_IMASK1(0);
  234. # ifdef SIC_IMASK2
  235. bfin_write_SIC_IMASK2(0);
  236. # endif
  237. #elif defined(SICA_IMASK0)
  238. bfin_write_SICA_IMASK0(0);
  239. bfin_write_SICA_IMASK1(0);
  240. #elif defined(SIC_IMASK)
  241. bfin_write_SIC_IMASK(0);
  242. #endif
  243. /* Set up a dummy NMI handler if needed. */
  244. if (CONFIG_BFIN_BOOT_MODE == BFIN_BOOT_BYPASS || ANOMALY_05000219)
  245. bfin_write_EVT2(evt_nmi); /* NMI */
  246. bfin_write_EVT5(evt_default); /* hardware error */
  247. bfin_write_EVT6(evt_default); /* core timer */
  248. bfin_write_EVT7(evt_default);
  249. bfin_write_EVT8(evt_default);
  250. bfin_write_EVT9(evt_default);
  251. bfin_write_EVT10(evt_default);
  252. bfin_write_EVT11(evt_default);
  253. bfin_write_EVT12(evt_default);
  254. bfin_write_EVT13(evt_default);
  255. bfin_write_EVT14(evt_default);
  256. bfin_write_EVT15(evt_default);
  257. bfin_write_ILAT(0);
  258. CSYNC();
  259. /* enable hardware error irq */
  260. irq_flags = 0x3f;
  261. local_irq_enable();
  262. return 0;
  263. }
  264. __attribute__ ((__noreturn__))
  265. void cpu_init_f(ulong bootflag, ulong loaded_from_ldr)
  266. {
  267. #ifndef CONFIG_BFIN_BOOTROM_USES_EVT1
  268. /* Build a NOP slide over the LDR jump block. Whee! */
  269. char nops[0xC];
  270. serial_early_puts("NOP Slide\n");
  271. memset(nops, 0x00, sizeof(nops));
  272. memcpy((void *)L1_INST_SRAM, nops, sizeof(nops));
  273. #endif
  274. if (!loaded_from_ldr) {
  275. /* Relocate sections into L1 if the LDR didn't do it -- don't
  276. * check length because the linker script does the size
  277. * checking at build time.
  278. */
  279. serial_early_puts("L1 Relocate\n");
  280. extern char _stext_l1[], _text_l1_lma[], _text_l1_len[];
  281. memcpy(&_stext_l1, &_text_l1_lma, (unsigned long)_text_l1_len);
  282. extern char _sdata_l1[], _data_l1_lma[], _data_l1_len[];
  283. memcpy(&_sdata_l1, &_data_l1_lma, (unsigned long)_data_l1_len);
  284. }
  285. /*
  286. * Make sure our async settings are committed. Some bootroms
  287. * (like the BF537) will reset some registers on us after it
  288. * has finished loading the LDR. Or if we're booting over
  289. * JTAG, the initcode never got a chance to run. Or if we
  290. * aren't booting from parallel flash, the initcode skipped
  291. * this step completely.
  292. */
  293. program_async_controller(NULL);
  294. /* Save RETX so we can pass it while booting Linux */
  295. bfin_poweron_retx = bootflag;
  296. #ifdef CONFIG_DEBUG_DUMP
  297. /* Turn on hardware trace buffer */
  298. bfin_write_TBUFCTL(TBUFPWR | TBUFEN);
  299. #endif
  300. #ifndef CONFIG_PANIC_HANG
  301. /* Reset upon a double exception rather than just hanging.
  302. * Do not do bfin_read on SWRST as that will reset status bits.
  303. */
  304. # ifdef SWRST
  305. bfin_write_SWRST(DOUBLE_FAULT);
  306. # endif
  307. #endif
  308. #if defined(CONFIG_CORE1_RUN) && defined(COREB_L1_CODE_START)
  309. bfin_core1_start();
  310. #endif
  311. serial_early_puts("Init global data\n");
  312. global_board_data_init();
  313. board_init_f(0);
  314. /* should not be reached */
  315. while (1);
  316. }
  317. int arch_cpu_init(void)
  318. {
  319. serial_early_puts("Init CPLB tables\n");
  320. init_cplbtables();
  321. serial_early_puts("Exceptions setup\n");
  322. exception_init();
  323. #ifndef CONFIG_ICACHE_OFF
  324. serial_early_puts("Turn on ICACHE\n");
  325. icache_enable();
  326. #endif
  327. #ifndef CONFIG_DCACHE_OFF
  328. serial_early_puts("Turn on DCACHE\n");
  329. dcache_enable();
  330. #endif
  331. #ifdef DEBUG
  332. if (GENERATED_GBL_DATA_SIZE < sizeof(*gd))
  333. hang();
  334. #endif
  335. /* Initialize */
  336. serial_early_puts("IRQ init\n");
  337. irq_init();
  338. return 0;
  339. }
  340. int arch_misc_init(void)
  341. {
  342. #if defined(CONFIG_SYS_I2C)
  343. i2c_reloc_fixup();
  344. #endif
  345. display_global_data();
  346. if (CONFIG_MEM_SIZE && bfin_os_log_check()) {
  347. puts("\nLog buffer from operating system:\n");
  348. bfin_os_log_dump();
  349. puts("\n");
  350. }
  351. return 0;
  352. }
  353. int interrupt_init(void)
  354. {
  355. return 0;
  356. }