cpu.c 9.7 KB

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