1/* 2 * File: arch/blackfin/kernel/setup.c 3 * Based on: 4 * Author: 5 * 6 * Created: 7 * Description: 8 * 9 * Modified: 10 * Copyright 2004-2006 Analog Devices Inc. 11 * 12 * Bugs: Enter bugs at http://blackfin.uclinux.org/ 13 * 14 * This program is free software; you can redistribute it and/or modify 15 * it under the terms of the GNU General Public License as published by 16 * the Free Software Foundation; either version 2 of the License, or 17 * (at your option) any later version. 18 * 19 * This program is distributed in the hope that it will be useful, 20 * but WITHOUT ANY WARRANTY; without even the implied warranty of 21 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 22 * GNU General Public License for more details. 23 * 24 * You should have received a copy of the GNU General Public License 25 * along with this program; if not, see the file COPYING, or write 26 * to the Free Software Foundation, Inc., 27 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA 28 */ 29 30#include <linux/delay.h> 31#include <linux/console.h> 32#include <linux/bootmem.h> 33#include <linux/seq_file.h> 34#include <linux/cpu.h> 35#include <linux/module.h> 36#include <linux/tty.h> 37 38#include <linux/ext2_fs.h> 39#include <linux/cramfs_fs.h> 40#include <linux/romfs_fs.h> 41 42#include <asm/cacheflush.h> 43#include <asm/blackfin.h> 44#include <asm/cplbinit.h> 45 46u16 _bfin_swrst; 47 48unsigned long memory_start, memory_end, physical_mem_end; 49unsigned long reserved_mem_dcache_on; 50unsigned long reserved_mem_icache_on; 51EXPORT_SYMBOL(memory_start); 52EXPORT_SYMBOL(memory_end); 53EXPORT_SYMBOL(physical_mem_end); 54EXPORT_SYMBOL(_ramend); 55 56#ifdef CONFIG_MTD_UCLINUX 57unsigned long memory_mtd_end, memory_mtd_start, mtd_size; 58unsigned long _ebss; 59EXPORT_SYMBOL(memory_mtd_end); 60EXPORT_SYMBOL(memory_mtd_start); 61EXPORT_SYMBOL(mtd_size); 62#endif 63 64char __initdata command_line[COMMAND_LINE_SIZE]; 65 66#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) 67static void generate_cpl_tables(void); 68#endif 69 70void __init bf53x_cache_init(void) 71{ 72#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) 73 generate_cpl_tables(); 74#endif 75 76#ifdef CONFIG_BLKFIN_CACHE 77 bfin_icache_init(); 78 printk(KERN_INFO "Instruction Cache Enabled\n"); 79#endif 80 81#ifdef CONFIG_BLKFIN_DCACHE 82 bfin_dcache_init(); 83 printk(KERN_INFO "Data Cache Enabled" 84# if defined CONFIG_BLKFIN_WB 85 " (write-back)" 86# elif defined CONFIG_BLKFIN_WT 87 " (write-through)" 88# endif 89 "\n"); 90#endif 91} 92 93void __init bf53x_relocate_l1_mem(void) 94{ 95 unsigned long l1_code_length; 96 unsigned long l1_data_a_length; 97 unsigned long l1_data_b_length; 98 99 l1_code_length = _etext_l1 - _stext_l1; 100 if (l1_code_length > L1_CODE_LENGTH) 101 l1_code_length = L1_CODE_LENGTH; 102 /* cannot complain as printk is not available as yet. 103 * But we can continue booting and complain later! 104 */ 105 106 /* Copy _stext_l1 to _etext_l1 to L1 instruction SRAM */ 107 dma_memcpy(_stext_l1, _l1_lma_start, l1_code_length); 108 109 l1_data_a_length = _ebss_l1 - _sdata_l1; 110 if (l1_data_a_length > L1_DATA_A_LENGTH) 111 l1_data_a_length = L1_DATA_A_LENGTH; 112 113 /* Copy _sdata_l1 to _ebss_l1 to L1 data bank A SRAM */ 114 dma_memcpy(_sdata_l1, _l1_lma_start + l1_code_length, l1_data_a_length); 115 116 l1_data_b_length = _ebss_b_l1 - _sdata_b_l1; 117 if (l1_data_b_length > L1_DATA_B_LENGTH) 118 l1_data_b_length = L1_DATA_B_LENGTH; 119 120 /* Copy _sdata_b_l1 to _ebss_b_l1 to L1 data bank B SRAM */ 121 dma_memcpy(_sdata_b_l1, _l1_lma_start + l1_code_length + 122 l1_data_a_length, l1_data_b_length); 123 124} 125 126static __init void parse_cmdline_early(char *cmdline_p) 127{ 128 char c = ' ', *to = cmdline_p; 129 unsigned int memsize; 130 for (;;) { 131 if (c == ' ') { 132 133 if (!memcmp(to, "mem=", 4)) { 134 to += 4; 135 memsize = memparse(to, &to); 136 if (memsize) 137 _ramend = memsize; 138 139 } else if (!memcmp(to, "max_mem=", 8)) { 140 to += 8; 141 memsize = memparse(to, &to); 142 if (memsize) { 143 physical_mem_end = memsize; 144 if (*to != ' ') { 145 if (*to == '$' 146 || *(to + 1) == '$') 147 reserved_mem_dcache_on = 148 1; 149 if (*to == '#' 150 || *(to + 1) == '#') 151 reserved_mem_icache_on = 152 1; 153 } 154 } 155 } 156 157 } 158 c = *(to++); 159 if (!c) 160 break; 161 } 162} 163 164void __init setup_arch(char **cmdline_p) 165{ 166 int bootmap_size; 167 unsigned long l1_length, sclk, cclk; 168#ifdef CONFIG_MTD_UCLINUX 169 unsigned long mtd_phys = 0; 170#endif 171 172#ifdef CONFIG_DUMMY_CONSOLE 173 conswitchp = &dummy_con; 174#endif 175 cclk = get_cclk(); 176 sclk = get_sclk(); 177 178#if !defined(CONFIG_BFIN_KERNEL_CLOCK) && defined(ANOMALY_05000273) 179 if (cclk == sclk) 180 panic("ANOMALY 05000273, SCLK can not be same as CCLK"); 181#endif 182 183#if defined(ANOMALY_05000266) 184 bfin_read_IMDMA_D0_IRQ_STATUS(); 185 bfin_read_IMDMA_D1_IRQ_STATUS(); 186#endif 187 188#ifdef DEBUG_SERIAL_EARLY_INIT 189 bfin_console_init(); /* early console registration */ 190 /* this give a chance to get printk() working before crash. */ 191#endif 192 193#if defined(CONFIG_CHR_DEV_FLASH) || defined(CONFIG_BLK_DEV_FLASH) 194 /* we need to initialize the Flashrom device here since we might 195 * do things with flash early on in the boot 196 */ 197 flash_probe(); 198#endif 199 200#if defined(CONFIG_CMDLINE_BOOL) 201 strncpy(&command_line[0], CONFIG_CMDLINE, sizeof(command_line)); 202 command_line[sizeof(command_line) - 1] = 0; 203#endif 204 205 /* Keep a copy of command line */ 206 *cmdline_p = &command_line[0]; 207 memcpy(boot_command_line, command_line, COMMAND_LINE_SIZE); 208 boot_command_line[COMMAND_LINE_SIZE - 1] = '\0'; 209 210 /* setup memory defaults from the user config */ 211 physical_mem_end = 0; 212 _ramend = CONFIG_MEM_SIZE * 1024 * 1024; 213 214 parse_cmdline_early(&command_line[0]); 215 216 if (physical_mem_end == 0) 217 physical_mem_end = _ramend; 218 219 /* by now the stack is part of the init task */ 220 memory_end = _ramend - DMA_UNCACHED_REGION; 221 222 _ramstart = (unsigned long)__bss_stop; 223 memory_start = PAGE_ALIGN(_ramstart); 224 225#if defined(CONFIG_MTD_UCLINUX) 226 /* generic memory mapped MTD driver */ 227 memory_mtd_end = memory_end; 228 229 mtd_phys = _ramstart; 230 mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 8))); 231 232# if defined(CONFIG_EXT2_FS) || defined(CONFIG_EXT3_FS) 233 if (*((unsigned short *)(mtd_phys + 0x438)) == EXT2_SUPER_MAGIC) 234 mtd_size = 235 PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x404)) << 10); 236# endif 237 238# if defined(CONFIG_CRAMFS) 239 if (*((unsigned long *)(mtd_phys)) == CRAMFS_MAGIC) 240 mtd_size = PAGE_ALIGN(*((unsigned long *)(mtd_phys + 0x4))); 241# endif 242 243# if defined(CONFIG_ROMFS_FS) 244 if (((unsigned long *)mtd_phys)[0] == ROMSB_WORD0 245 && ((unsigned long *)mtd_phys)[1] == ROMSB_WORD1) 246 mtd_size = 247 PAGE_ALIGN(be32_to_cpu(((unsigned long *)mtd_phys)[2])); 248# if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) 249 /* Due to a Hardware Anomaly we need to limit the size of usable 250 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on 251 * 05000263 - Hardware loop corrupted when taking an ICPLB exception 252 */ 253# if defined(CONFIG_DEBUG_HUNT_FOR_ZERO) 254 if (memory_end >= 56 * 1024 * 1024) 255 memory_end = 56 * 1024 * 1024; 256# else 257 if (memory_end >= 60 * 1024 * 1024) 258 memory_end = 60 * 1024 * 1024; 259# endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ 260# endif /* ANOMALY_05000263 */ 261# endif /* CONFIG_ROMFS_FS */ 262 263 memory_end -= mtd_size; 264 265 if (mtd_size == 0) { 266 console_init(); 267 panic("Don't boot kernel without rootfs attached.\n"); 268 } 269 270 /* Relocate MTD image to the top of memory after the uncached memory area */ 271 dma_memcpy((char *)memory_end, __bss_stop, mtd_size); 272 273 memory_mtd_start = memory_end; 274 _ebss = memory_mtd_start; /* define _ebss for compatible */ 275#endif /* CONFIG_MTD_UCLINUX */ 276 277#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) 278 /* Due to a Hardware Anomaly we need to limit the size of usable 279 * instruction memory to max 60MB, 56 if HUNT_FOR_ZERO is on 280 * 05000263 - Hardware loop corrupted when taking an ICPLB exception 281 */ 282#if defined(CONFIG_DEBUG_HUNT_FOR_ZERO) 283 if (memory_end >= 56 * 1024 * 1024) 284 memory_end = 56 * 1024 * 1024; 285#else 286 if (memory_end >= 60 * 1024 * 1024) 287 memory_end = 60 * 1024 * 1024; 288#endif /* CONFIG_DEBUG_HUNT_FOR_ZERO */ 289 printk(KERN_NOTICE "Warning: limiting memory to %liMB due to hardware anomaly 05000263\n", memory_end >> 20); 290#endif /* ANOMALY_05000263 */ 291 292#if !defined(CONFIG_MTD_UCLINUX) 293 memory_end -= SIZE_4K; /*In case there is no valid CPLB behind memory_end make sure we don't get to close*/ 294#endif 295 init_mm.start_code = (unsigned long)_stext; 296 init_mm.end_code = (unsigned long)_etext; 297 init_mm.end_data = (unsigned long)_edata; 298 init_mm.brk = (unsigned long)0; 299 300 init_leds(); 301 302 printk(KERN_INFO "Blackfin support (C) 2004-2007 Analog Devices, Inc.\n"); 303 if (bfin_compiled_revid() == 0xffff) 304 printk(KERN_INFO "Compiled for ADSP-%s Rev any\n", CPU); 305 else if (bfin_compiled_revid() == -1) 306 printk(KERN_INFO "Compiled for ADSP-%s Rev none\n", CPU); 307 else 308 printk(KERN_INFO "Compiled for ADSP-%s Rev 0.%d\n", CPU, bfin_compiled_revid()); 309 if (bfin_revid() != bfin_compiled_revid()) { 310 if (bfin_compiled_revid() == -1) 311 printk(KERN_ERR "Warning: Compiled for Rev none, but running on Rev %d\n", 312 bfin_revid()); 313 else if (bfin_compiled_revid() != 0xffff) 314 printk(KERN_ERR "Warning: Compiled for Rev %d, but running on Rev %d\n", 315 bfin_compiled_revid(), bfin_revid()); 316 } 317 if (bfin_revid() < SUPPORTED_REVID) 318 printk(KERN_ERR "Warning: Unsupported Chip Revision ADSP-%s Rev 0.%d detected\n", 319 CPU, bfin_revid()); 320 printk(KERN_INFO "Blackfin Linux support by http://blackfin.uclinux.org/\n"); 321 322 printk(KERN_INFO "Processor Speed: %lu MHz core clock and %lu Mhz System Clock\n", 323 cclk / 1000000, sclk / 1000000); 324 325#if defined(ANOMALY_05000273) 326 if ((cclk >> 1) <= sclk) 327 printk("\n\n\nANOMALY_05000273: CCLK must be >= 2*SCLK !!!\n\n\n"); 328#endif 329 330 printk(KERN_INFO "Board Memory: %ldMB\n", physical_mem_end >> 20); 331 printk(KERN_INFO "Kernel Managed Memory: %ldMB\n", _ramend >> 20); 332 333 printk(KERN_INFO "Memory map:\n" 334 KERN_INFO " text = 0x%p-0x%p\n" 335 KERN_INFO " rodata = 0x%p-0x%p\n" 336 KERN_INFO " data = 0x%p-0x%p\n" 337 KERN_INFO " stack = 0x%p-0x%p\n" 338 KERN_INFO " init = 0x%p-0x%p\n" 339 KERN_INFO " bss = 0x%p-0x%p\n" 340 KERN_INFO " available = 0x%p-0x%p\n" 341#ifdef CONFIG_MTD_UCLINUX 342 KERN_INFO " rootfs = 0x%p-0x%p\n" 343#endif 344#if DMA_UNCACHED_REGION > 0 345 KERN_INFO " DMA Zone = 0x%p-0x%p\n" 346#endif 347 , _stext, _etext, 348 __start_rodata, __end_rodata, 349 _sdata, _edata, 350 (void*)&init_thread_union, (void*)((int)(&init_thread_union) + 0x2000), 351 __init_begin, __init_end, 352 __bss_start, __bss_stop, 353 (void*)_ramstart, (void*)memory_end 354#ifdef CONFIG_MTD_UCLINUX 355 , (void*)memory_mtd_start, (void*)(memory_mtd_start + mtd_size) 356#endif 357#if DMA_UNCACHED_REGION > 0 358 , (void*)(_ramend - DMA_UNCACHED_REGION), (void*)(_ramend) 359#endif 360 ); 361 362 /* 363 * give all the memory to the bootmap allocator, tell it to put the 364 * boot mem_map at the start of memory 365 */ 366 bootmap_size = init_bootmem_node(NODE_DATA(0), memory_start >> PAGE_SHIFT, /* map goes here */ 367 PAGE_OFFSET >> PAGE_SHIFT, 368 memory_end >> PAGE_SHIFT); 369 /* 370 * free the usable memory, we have to make sure we do not free 371 * the bootmem bitmap so we then reserve it after freeing it :-) 372 */ 373 free_bootmem(memory_start, memory_end - memory_start); 374 375 reserve_bootmem(memory_start, bootmap_size); 376 /* 377 * get kmalloc into gear 378 */ 379 paging_init(); 380 381 /* check the size of the l1 area */ 382 l1_length = _etext_l1 - _stext_l1; 383 if (l1_length > L1_CODE_LENGTH) 384 panic("L1 memory overflow\n"); 385 386 l1_length = _ebss_l1 - _sdata_l1; 387 if (l1_length > L1_DATA_A_LENGTH) 388 panic("L1 memory overflow\n"); 389 390#ifdef BF561_FAMILY 391 _bfin_swrst = bfin_read_SICA_SWRST(); 392#else 393 _bfin_swrst = bfin_read_SWRST(); 394#endif 395 396 bf53x_cache_init(); 397 398 printk(KERN_INFO "Hardware Trace Enabled\n"); 399 bfin_write_TBUFCTL(0x03); 400} 401 402static int __init topology_init(void) 403{ 404#if defined(CONFIG_BF561) 405 static struct cpu cpu[2]; 406 register_cpu(&cpu[0], 0); 407 register_cpu(&cpu[1], 1); 408 return 0; 409#else 410 static struct cpu cpu[1]; 411 return register_cpu(cpu, 0); 412#endif 413} 414 415subsys_initcall(topology_init); 416 417#if defined(CONFIG_BLKFIN_DCACHE) || defined(CONFIG_BLKFIN_CACHE) 418static u16 __init lock_kernel_check(u32 start, u32 end) 419{ 420 if ((start <= (u32) _stext && end >= (u32) _end) 421 || (start >= (u32) _stext && end <= (u32) _end)) 422 return IN_KERNEL; 423 return 0; 424} 425 426static unsigned short __init 427fill_cplbtab(struct cplb_tab *table, 428 unsigned long start, unsigned long end, 429 unsigned long block_size, unsigned long cplb_data) 430{ 431 int i; 432 433 switch (block_size) { 434 case SIZE_4M: 435 i = 3; 436 break; 437 case SIZE_1M: 438 i = 2; 439 break; 440 case SIZE_4K: 441 i = 1; 442 break; 443 case SIZE_1K: 444 default: 445 i = 0; 446 break; 447 } 448 449 cplb_data = (cplb_data & ~(3 << 16)) | (i << 16); 450 451 while ((start < end) && (table->pos < table->size)) { 452 453 table->tab[table->pos++] = start; 454 455 if (lock_kernel_check(start, start + block_size) == IN_KERNEL) 456 table->tab[table->pos++] = 457 cplb_data | CPLB_LOCK | CPLB_DIRTY; 458 else 459 table->tab[table->pos++] = cplb_data; 460 461 start += block_size; 462 } 463 return 0; 464} 465 466static unsigned short __init 467close_cplbtab(struct cplb_tab *table) 468{ 469 470 while (table->pos < table->size) { 471 472 table->tab[table->pos++] = 0; 473 table->tab[table->pos++] = 0; /* !CPLB_VALID */ 474 } 475 return 0; 476} 477 478/* helper function */ 479static void __fill_code_cplbtab(struct cplb_tab *t, int i, 480 u32 a_start, u32 a_end) 481{ 482 if (cplb_data[i].psize) { 483 fill_cplbtab(t, 484 cplb_data[i].start, 485 cplb_data[i].end, 486 cplb_data[i].psize, 487 cplb_data[i].i_conf); 488 } else { 489#if (defined(CONFIG_BLKFIN_CACHE) && defined(ANOMALY_05000263)) 490 if (i == SDRAM_KERN) { 491 fill_cplbtab(t, 492 cplb_data[i].start, 493 cplb_data[i].end, 494 SIZE_4M, 495 cplb_data[i].i_conf); 496 } else { 497#endif 498 fill_cplbtab(t, 499 cplb_data[i].start, 500 a_start, 501 SIZE_1M, 502 cplb_data[i].i_conf); 503 fill_cplbtab(t, 504 a_start, 505 a_end, 506 SIZE_4M, 507 cplb_data[i].i_conf); 508 fill_cplbtab(t, a_end, 509 cplb_data[i].end, 510 SIZE_1M, 511 cplb_data[i].i_conf); 512 } 513 } 514} 515 516static void __fill_data_cplbtab(struct cplb_tab *t, int i, 517 u32 a_start, u32 a_end) 518{ 519 if (cplb_data[i].psize) { 520 fill_cplbtab(t, 521 cplb_data[i].start, 522 cplb_data[i].end, 523 cplb_data[i].psize, 524 cplb_data[i].d_conf); 525 } else { 526 fill_cplbtab(t, 527 cplb_data[i].start, 528 a_start, SIZE_1M, 529 cplb_data[i].d_conf); 530 fill_cplbtab(t, a_start, 531 a_end, SIZE_4M, 532 cplb_data[i].d_conf); 533 fill_cplbtab(t, a_end, 534 cplb_data[i].end, 535 SIZE_1M, 536 cplb_data[i].d_conf); 537 } 538} 539static void __init generate_cpl_tables(void) 540{ 541 542 u16 i, j, process; 543 u32 a_start, a_end, as, ae, as_1m; 544 545 struct cplb_tab *t_i = NULL; 546 struct cplb_tab *t_d = NULL; 547 struct s_cplb cplb; 548 549 cplb.init_i.size = MAX_CPLBS; 550 cplb.init_d.size = MAX_CPLBS; 551 cplb.switch_i.size = MAX_SWITCH_I_CPLBS; 552 cplb.switch_d.size = MAX_SWITCH_D_CPLBS; 553 554 cplb.init_i.pos = 0; 555 cplb.init_d.pos = 0; 556 cplb.switch_i.pos = 0; 557 cplb.switch_d.pos = 0; 558 559 cplb.init_i.tab = icplb_table; 560 cplb.init_d.tab = dcplb_table; 561 cplb.switch_i.tab = ipdt_table; 562 cplb.switch_d.tab = dpdt_table; 563 564 cplb_data[SDRAM_KERN].end = memory_end; 565 566#ifdef CONFIG_MTD_UCLINUX 567 cplb_data[SDRAM_RAM_MTD].start = memory_mtd_start; 568 cplb_data[SDRAM_RAM_MTD].end = memory_mtd_start + mtd_size; 569 cplb_data[SDRAM_RAM_MTD].valid = mtd_size > 0; 570# if defined(CONFIG_ROMFS_FS) 571 cplb_data[SDRAM_RAM_MTD].attr |= I_CPLB; 572 573 574 cplb_data[SDRAM_KERN].end = memory_mtd_start + mtd_size;; 575 cplb_data[SDRAM_RAM_MTD].valid = 0; 576 577# endif 578#else 579 cplb_data[SDRAM_RAM_MTD].valid = 0; 580#endif 581 582 cplb_data[SDRAM_DMAZ].start = _ramend - DMA_UNCACHED_REGION; 583 cplb_data[SDRAM_DMAZ].end = _ramend; 584 585 cplb_data[RES_MEM].start = _ramend; 586 cplb_data[RES_MEM].end = physical_mem_end; 587 588 if (reserved_mem_dcache_on) 589 cplb_data[RES_MEM].d_conf = SDRAM_DGENERIC; 590 else 591 cplb_data[RES_MEM].d_conf = SDRAM_DNON_CHBL; 592 593 if (reserved_mem_icache_on) 594 cplb_data[RES_MEM].i_conf = SDRAM_IGENERIC; 595 else 596 cplb_data[RES_MEM].i_conf = SDRAM_INON_CHBL; 597 598 for (i = ZERO_P; i <= L2_MEM; i++) { 599 if (!cplb_data[i].valid) 600 continue; 601 602 as_1m = cplb_data[i].start % SIZE_1M; 603 604 /* 605 * We need to make sure all sections are properly 1M aligned 606 * However between Kernel Memory and the Kernel mtd section, 607 * depending on the rootfs size, there can be overlapping 608 * memory areas. 609 */ 610 611 if (as_1m && i != L1I_MEM && i != L1D_MEM) { 612#ifdef CONFIG_MTD_UCLINUX 613 if (i == SDRAM_RAM_MTD) { 614 if ((cplb_data[SDRAM_KERN].end + 1) > 615 cplb_data[SDRAM_RAM_MTD].start) 616 cplb_data[SDRAM_RAM_MTD].start = 617 (cplb_data[i].start & 618 (-2*SIZE_1M)) + SIZE_1M; 619 else 620 cplb_data[SDRAM_RAM_MTD].start = 621 (cplb_data[i].start & 622 (-2*SIZE_1M)); 623 } else 624#endif 625 printk(KERN_WARNING 626 "Unaligned Start of %s at 0x%X\n", 627 cplb_data[i].name, cplb_data[i].start); 628 } 629 630 as = cplb_data[i].start % SIZE_4M; 631 ae = cplb_data[i].end % SIZE_4M; 632 633 if (as) 634 a_start = cplb_data[i].start + (SIZE_4M - (as)); 635 else 636 a_start = cplb_data[i].start; 637 638 a_end = cplb_data[i].end - ae; 639 640 for (j = INITIAL_T; j <= SWITCH_T; j++) { 641 642 switch (j) { 643 case INITIAL_T: 644 if (cplb_data[i].attr & INITIAL_T) { 645 t_i = &cplb.init_i; 646 t_d = &cplb.init_d; 647 process = 1; 648 } else 649 process = 0; 650 break; 651 case SWITCH_T: 652 if (cplb_data[i].attr & SWITCH_T) { 653 t_i = &cplb.switch_i; 654 t_d = &cplb.switch_d; 655 process = 1; 656 } else 657 process = 0; 658 break; 659 default: 660 process = 0; 661 break; 662 } 663 664 if (!process) 665 continue; 666 if (cplb_data[i].attr & I_CPLB) 667 __fill_code_cplbtab(t_i, i, a_start, a_end); 668 669 if (cplb_data[i].attr & D_CPLB) 670 __fill_data_cplbtab(t_d, i, a_start, a_end); 671 } 672 } 673 674/* close tables */ 675 676 close_cplbtab(&cplb.init_i); 677 close_cplbtab(&cplb.init_d); 678 679 cplb.init_i.tab[cplb.init_i.pos] = -1; 680 cplb.init_d.tab[cplb.init_d.pos] = -1; 681 cplb.switch_i.tab[cplb.switch_i.pos] = -1; 682 cplb.switch_d.tab[cplb.switch_d.pos] = -1; 683 684} 685 686#endif 687 688static u_long get_vco(void) 689{ 690 u_long msel; 691 u_long vco; 692 693 msel = (bfin_read_PLL_CTL() >> 9) & 0x3F; 694 if (0 == msel) 695 msel = 64; 696 697 vco = CONFIG_CLKIN_HZ; 698 vco >>= (1 & bfin_read_PLL_CTL()); /* DF bit */ 699 vco = msel * vco; 700 return vco; 701} 702 703/*Get the Core clock*/ 704u_long get_cclk(void) 705{ 706 u_long csel, ssel; 707 if (bfin_read_PLL_STAT() & 0x1) 708 return CONFIG_CLKIN_HZ; 709 710 ssel = bfin_read_PLL_DIV(); 711 csel = ((ssel >> 4) & 0x03); 712 ssel &= 0xf; 713 if (ssel && ssel < (1 << csel)) /* SCLK > CCLK */ 714 return get_vco() / ssel; 715 return get_vco() >> csel; 716} 717 718EXPORT_SYMBOL(get_cclk); 719 720/* Get the System clock */ 721u_long get_sclk(void) 722{ 723 u_long ssel; 724 725 if (bfin_read_PLL_STAT() & 0x1) 726 return CONFIG_CLKIN_HZ; 727 728 ssel = (bfin_read_PLL_DIV() & 0xf); 729 if (0 == ssel) { 730 printk(KERN_WARNING "Invalid System Clock\n"); 731 ssel = 1; 732 } 733 734 return get_vco() / ssel; 735} 736 737EXPORT_SYMBOL(get_sclk); 738 739/* 740 * Get CPU information for use by the procfs. 741 */ 742static int show_cpuinfo(struct seq_file *m, void *v) 743{ 744 char *cpu, *mmu, *fpu, *name; 745 uint32_t revid; 746 747 u_long cclk = 0, sclk = 0; 748 u_int dcache_size = 0, dsup_banks = 0; 749 750 cpu = CPU; 751 mmu = "none"; 752 fpu = "none"; 753 revid = bfin_revid(); 754 name = bfin_board_name; 755 756 cclk = get_cclk(); 757 sclk = get_sclk(); 758 759 seq_printf(m, "CPU:\t\tADSP-%s Rev. 0.%d\n" 760 "MMU:\t\t%s\n" 761 "FPU:\t\t%s\n" 762 "Core Clock:\t%9lu Hz\n" 763 "System Clock:\t%9lu Hz\n" 764 "BogoMips:\t%lu.%02lu\n" 765 "Calibration:\t%lu loops\n", 766 cpu, revid, mmu, fpu, 767 cclk, 768 sclk, 769 (loops_per_jiffy * HZ) / 500000, 770 ((loops_per_jiffy * HZ) / 5000) % 100, 771 (loops_per_jiffy * HZ)); 772 seq_printf(m, "Board Name:\t%s\n", name); 773 seq_printf(m, "Board Memory:\t%ld MB\n", physical_mem_end >> 20); 774 seq_printf(m, "Kernel Memory:\t%ld MB\n", (unsigned long)_ramend >> 20); 775 if (bfin_read_IMEM_CONTROL() & (ENICPLB | IMC)) 776 seq_printf(m, "I-CACHE:\tON\n"); 777 else 778 seq_printf(m, "I-CACHE:\tOFF\n"); 779 if ((bfin_read_DMEM_CONTROL()) & (ENDCPLB | DMC_ENABLE)) 780 seq_printf(m, "D-CACHE:\tON" 781#if defined CONFIG_BLKFIN_WB 782 " (write-back)" 783#elif defined CONFIG_BLKFIN_WT 784 " (write-through)" 785#endif 786 "\n"); 787 else 788 seq_printf(m, "D-CACHE:\tOFF\n"); 789 790 791 switch(bfin_read_DMEM_CONTROL() & (1 << DMC0_P | 1 << DMC1_P)) { 792 case ACACHE_BSRAM: 793 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tSRAM\n"); 794 dcache_size = 16; 795 dsup_banks = 1; 796 break; 797 case ACACHE_BCACHE: 798 seq_printf(m, "DBANK-A:\tCACHE\n" "DBANK-B:\tCACHE\n"); 799 dcache_size = 32; 800 dsup_banks = 2; 801 break; 802 case ASRAM_BSRAM: 803 seq_printf(m, "DBANK-A:\tSRAM\n" "DBANK-B:\tSRAM\n"); 804 dcache_size = 0; 805 dsup_banks = 0; 806 break; 807 default: 808 break; 809 } 810 811 812 seq_printf(m, "I-CACHE Size:\t%dKB\n", BLKFIN_ICACHESIZE / 1024); 813 seq_printf(m, "D-CACHE Size:\t%dKB\n", dcache_size); 814 seq_printf(m, "I-CACHE Setup:\t%d Sub-banks/%d Ways, %d Lines/Way\n", 815 BLKFIN_ISUBBANKS, BLKFIN_IWAYS, BLKFIN_ILINES); 816 seq_printf(m, 817 "D-CACHE Setup:\t%d Super-banks/%d Sub-banks/%d Ways, %d Lines/Way\n", 818 dsup_banks, BLKFIN_DSUBBANKS, BLKFIN_DWAYS, 819 BLKFIN_DLINES); 820#ifdef CONFIG_BLKFIN_CACHE_LOCK 821 switch (read_iloc()) { 822 case WAY0_L: 823 seq_printf(m, "Way0 Locked-Down\n"); 824 break; 825 case WAY1_L: 826 seq_printf(m, "Way1 Locked-Down\n"); 827 break; 828 case WAY01_L: 829 seq_printf(m, "Way0,Way1 Locked-Down\n"); 830 break; 831 case WAY2_L: 832 seq_printf(m, "Way2 Locked-Down\n"); 833 break; 834 case WAY02_L: 835 seq_printf(m, "Way0,Way2 Locked-Down\n"); 836 break; 837 case WAY12_L: 838 seq_printf(m, "Way1,Way2 Locked-Down\n"); 839 break; 840 case WAY012_L: 841 seq_printf(m, "Way0,Way1 & Way2 Locked-Down\n"); 842 break; 843 case WAY3_L: 844 seq_printf(m, "Way3 Locked-Down\n"); 845 break; 846 case WAY03_L: 847 seq_printf(m, "Way0,Way3 Locked-Down\n"); 848 break; 849 case WAY13_L: 850 seq_printf(m, "Way1,Way3 Locked-Down\n"); 851 break; 852 case WAY013_L: 853 seq_printf(m, "Way 0,Way1,Way3 Locked-Down\n"); 854 break; 855 case WAY32_L: 856 seq_printf(m, "Way3,Way2 Locked-Down\n"); 857 break; 858 case WAY320_L: 859 seq_printf(m, "Way3,Way2,Way0 Locked-Down\n"); 860 break; 861 case WAY321_L: 862 seq_printf(m, "Way3,Way2,Way1 Locked-Down\n"); 863 break; 864 case WAYALL_L: 865 seq_printf(m, "All Ways are locked\n"); 866 break; 867 default: 868 seq_printf(m, "No Ways are locked\n"); 869 } 870#endif 871 return 0; 872} 873 874static void *c_start(struct seq_file *m, loff_t *pos) 875{ 876 return *pos < NR_CPUS ? ((void *)0x12345678) : NULL; 877} 878 879static void *c_next(struct seq_file *m, void *v, loff_t *pos) 880{ 881 ++*pos; 882 return c_start(m, pos); 883} 884 885static void c_stop(struct seq_file *m, void *v) 886{ 887} 888 889struct seq_operations cpuinfo_op = { 890 .start = c_start, 891 .next = c_next, 892 .stop = c_stop, 893 .show = show_cpuinfo, 894}; 895 896void __init cmdline_init(const char *r0) 897{ 898 if (r0) 899 strncpy(command_line, r0, COMMAND_LINE_SIZE); 900} 901