diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-30 14:45:52 -0400 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2012-07-30 14:45:52 -0400 |
commit | 287dc4b7642df15fa6b9f286c812e79138acd698 (patch) | |
tree | c3ebe1caea100ff2b8f414619ec0a9dcd8a14547 /arch/mips/kernel | |
parent | 720d85075b7ed3617de8ca8d9097390e303e9f60 (diff) | |
parent | 68d8848567ef03eb2c2303173934428d0bf0a531 (diff) |
Merge branch 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus
Pull MIPS updates from Ralf Baechle:
"More hardware support across the field including a bunch of device
drivers. The highlight however really are further steps towards
device tree.
This has been sitting in -next for ages. All MIPS _defconfigs have
been tested to boot or where I don't have hardware available, to at
least build fine."
* 'upstream' of git://git.linux-mips.org/pub/scm/ralf/upstream-linus: (77 commits)
MIPS: Loongson 1B: Add defconfig
MIPS: Loongson 1B: Add board support
MIPS: Netlogic: early console fix
MIPS: Netlogic: Fix indentation of smpboot.S
MIPS: Netlogic: remove cpu_has_dc_aliases define for XLP
MIPS: Netlogic: Remove unused pcibios_fixups
MIPS: Netlogic: Add XLP SoC devices in FDT
MIPS: Netlogic: Add IRQ mappings for more devices
MIPS: Netlogic: USB support for XLP
MIPS: Netlogic: XLP PCIe controller support.
MIPS: Netlogic: Platform changes for XLR/XLS I2C
MIPS: Netlogic: Platform NAND/NOR flash support
MIPS: Netlogic: Platform changes for XLS USB
MIPS: Netlogic: Remove NETLOGIC_ prefix
MIPS: Netlogic: SMP wakeup code update
MIPS: Netlogic: Update comments in smpboot.S
MIPS: BCM63XX: Add 96328avng reference board
MIPS: Expose PCIe drivers for MIPS
MIPS: BCM63XX: Add PCIe Support for BCM6328
MIPS: BCM63XX: Move the PCI initialization into its own function
...
Diffstat (limited to 'arch/mips/kernel')
-rw-r--r-- | arch/mips/kernel/cpu-probe.c | 299 | ||||
-rw-r--r-- | arch/mips/kernel/perf_event_mipsxx.c | 5 | ||||
-rw-r--r-- | arch/mips/kernel/prom.c | 29 | ||||
-rw-r--r-- | arch/mips/kernel/smp.c | 4 | ||||
-rw-r--r-- | arch/mips/kernel/smtc.c | 76 | ||||
-rw-r--r-- | arch/mips/kernel/traps.c | 1 |
6 files changed, 233 insertions, 181 deletions
diff --git a/arch/mips/kernel/cpu-probe.c b/arch/mips/kernel/cpu-probe.c index f4630e1082ab..1b51046191e8 100644 --- a/arch/mips/kernel/cpu-probe.c +++ b/arch/mips/kernel/cpu-probe.c | |||
@@ -190,6 +190,7 @@ void __init check_wait(void) | |||
190 | case CPU_CAVIUM_OCTEON_PLUS: | 190 | case CPU_CAVIUM_OCTEON_PLUS: |
191 | case CPU_CAVIUM_OCTEON2: | 191 | case CPU_CAVIUM_OCTEON2: |
192 | case CPU_JZRISC: | 192 | case CPU_JZRISC: |
193 | case CPU_LOONGSON1: | ||
193 | case CPU_XLR: | 194 | case CPU_XLR: |
194 | case CPU_XLP: | 195 | case CPU_XLP: |
195 | cpu_wait = r4k_wait; | 196 | cpu_wait = r4k_wait; |
@@ -330,6 +331,154 @@ static inline void cpu_probe_vmbits(struct cpuinfo_mips *c) | |||
330 | #endif | 331 | #endif |
331 | } | 332 | } |
332 | 333 | ||
334 | static char unknown_isa[] __cpuinitdata = KERN_ERR \ | ||
335 | "Unsupported ISA type, c0.config0: %d."; | ||
336 | |||
337 | static inline unsigned int decode_config0(struct cpuinfo_mips *c) | ||
338 | { | ||
339 | unsigned int config0; | ||
340 | int isa; | ||
341 | |||
342 | config0 = read_c0_config(); | ||
343 | |||
344 | if (((config0 & MIPS_CONF_MT) >> 7) == 1) | ||
345 | c->options |= MIPS_CPU_TLB; | ||
346 | isa = (config0 & MIPS_CONF_AT) >> 13; | ||
347 | switch (isa) { | ||
348 | case 0: | ||
349 | switch ((config0 & MIPS_CONF_AR) >> 10) { | ||
350 | case 0: | ||
351 | c->isa_level = MIPS_CPU_ISA_M32R1; | ||
352 | break; | ||
353 | case 1: | ||
354 | c->isa_level = MIPS_CPU_ISA_M32R2; | ||
355 | break; | ||
356 | default: | ||
357 | goto unknown; | ||
358 | } | ||
359 | break; | ||
360 | case 2: | ||
361 | switch ((config0 & MIPS_CONF_AR) >> 10) { | ||
362 | case 0: | ||
363 | c->isa_level = MIPS_CPU_ISA_M64R1; | ||
364 | break; | ||
365 | case 1: | ||
366 | c->isa_level = MIPS_CPU_ISA_M64R2; | ||
367 | break; | ||
368 | default: | ||
369 | goto unknown; | ||
370 | } | ||
371 | break; | ||
372 | default: | ||
373 | goto unknown; | ||
374 | } | ||
375 | |||
376 | return config0 & MIPS_CONF_M; | ||
377 | |||
378 | unknown: | ||
379 | panic(unknown_isa, config0); | ||
380 | } | ||
381 | |||
382 | static inline unsigned int decode_config1(struct cpuinfo_mips *c) | ||
383 | { | ||
384 | unsigned int config1; | ||
385 | |||
386 | config1 = read_c0_config1(); | ||
387 | |||
388 | if (config1 & MIPS_CONF1_MD) | ||
389 | c->ases |= MIPS_ASE_MDMX; | ||
390 | if (config1 & MIPS_CONF1_WR) | ||
391 | c->options |= MIPS_CPU_WATCH; | ||
392 | if (config1 & MIPS_CONF1_CA) | ||
393 | c->ases |= MIPS_ASE_MIPS16; | ||
394 | if (config1 & MIPS_CONF1_EP) | ||
395 | c->options |= MIPS_CPU_EJTAG; | ||
396 | if (config1 & MIPS_CONF1_FP) { | ||
397 | c->options |= MIPS_CPU_FPU; | ||
398 | c->options |= MIPS_CPU_32FPR; | ||
399 | } | ||
400 | if (cpu_has_tlb) | ||
401 | c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; | ||
402 | |||
403 | return config1 & MIPS_CONF_M; | ||
404 | } | ||
405 | |||
406 | static inline unsigned int decode_config2(struct cpuinfo_mips *c) | ||
407 | { | ||
408 | unsigned int config2; | ||
409 | |||
410 | config2 = read_c0_config2(); | ||
411 | |||
412 | if (config2 & MIPS_CONF2_SL) | ||
413 | c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; | ||
414 | |||
415 | return config2 & MIPS_CONF_M; | ||
416 | } | ||
417 | |||
418 | static inline unsigned int decode_config3(struct cpuinfo_mips *c) | ||
419 | { | ||
420 | unsigned int config3; | ||
421 | |||
422 | config3 = read_c0_config3(); | ||
423 | |||
424 | if (config3 & MIPS_CONF3_SM) | ||
425 | c->ases |= MIPS_ASE_SMARTMIPS; | ||
426 | if (config3 & MIPS_CONF3_DSP) | ||
427 | c->ases |= MIPS_ASE_DSP; | ||
428 | if (config3 & MIPS_CONF3_VINT) | ||
429 | c->options |= MIPS_CPU_VINT; | ||
430 | if (config3 & MIPS_CONF3_VEIC) | ||
431 | c->options |= MIPS_CPU_VEIC; | ||
432 | if (config3 & MIPS_CONF3_MT) | ||
433 | c->ases |= MIPS_ASE_MIPSMT; | ||
434 | if (config3 & MIPS_CONF3_ULRI) | ||
435 | c->options |= MIPS_CPU_ULRI; | ||
436 | |||
437 | return config3 & MIPS_CONF_M; | ||
438 | } | ||
439 | |||
440 | static inline unsigned int decode_config4(struct cpuinfo_mips *c) | ||
441 | { | ||
442 | unsigned int config4; | ||
443 | |||
444 | config4 = read_c0_config4(); | ||
445 | |||
446 | if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT | ||
447 | && cpu_has_tlb) | ||
448 | c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40; | ||
449 | |||
450 | c->kscratch_mask = (config4 >> 16) & 0xff; | ||
451 | |||
452 | return config4 & MIPS_CONF_M; | ||
453 | } | ||
454 | |||
455 | static void __cpuinit decode_configs(struct cpuinfo_mips *c) | ||
456 | { | ||
457 | int ok; | ||
458 | |||
459 | /* MIPS32 or MIPS64 compliant CPU. */ | ||
460 | c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | | ||
461 | MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; | ||
462 | |||
463 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; | ||
464 | |||
465 | ok = decode_config0(c); /* Read Config registers. */ | ||
466 | BUG_ON(!ok); /* Arch spec violation! */ | ||
467 | if (ok) | ||
468 | ok = decode_config1(c); | ||
469 | if (ok) | ||
470 | ok = decode_config2(c); | ||
471 | if (ok) | ||
472 | ok = decode_config3(c); | ||
473 | if (ok) | ||
474 | ok = decode_config4(c); | ||
475 | |||
476 | mips_probe_watch_registers(c); | ||
477 | |||
478 | if (cpu_has_mips_r2) | ||
479 | c->core = read_c0_ebase() & 0x3ff; | ||
480 | } | ||
481 | |||
333 | #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ | 482 | #define R4K_OPTS (MIPS_CPU_TLB | MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE \ |
334 | | MIPS_CPU_COUNTER) | 483 | | MIPS_CPU_COUNTER) |
335 | 484 | ||
@@ -638,155 +787,19 @@ static inline void cpu_probe_legacy(struct cpuinfo_mips *c, unsigned int cpu) | |||
638 | MIPS_CPU_32FPR; | 787 | MIPS_CPU_32FPR; |
639 | c->tlbsize = 64; | 788 | c->tlbsize = 64; |
640 | break; | 789 | break; |
641 | } | 790 | case PRID_IMP_LOONGSON1: |
642 | } | 791 | decode_configs(c); |
643 | |||
644 | static char unknown_isa[] __cpuinitdata = KERN_ERR \ | ||
645 | "Unsupported ISA type, c0.config0: %d."; | ||
646 | 792 | ||
647 | static inline unsigned int decode_config0(struct cpuinfo_mips *c) | 793 | c->cputype = CPU_LOONGSON1; |
648 | { | ||
649 | unsigned int config0; | ||
650 | int isa; | ||
651 | 794 | ||
652 | config0 = read_c0_config(); | 795 | switch (c->processor_id & PRID_REV_MASK) { |
653 | 796 | case PRID_REV_LOONGSON1B: | |
654 | if (((config0 & MIPS_CONF_MT) >> 7) == 1) | 797 | __cpu_name[cpu] = "Loongson 1B"; |
655 | c->options |= MIPS_CPU_TLB; | ||
656 | isa = (config0 & MIPS_CONF_AT) >> 13; | ||
657 | switch (isa) { | ||
658 | case 0: | ||
659 | switch ((config0 & MIPS_CONF_AR) >> 10) { | ||
660 | case 0: | ||
661 | c->isa_level = MIPS_CPU_ISA_M32R1; | ||
662 | break; | ||
663 | case 1: | ||
664 | c->isa_level = MIPS_CPU_ISA_M32R2; | ||
665 | break; | 798 | break; |
666 | default: | ||
667 | goto unknown; | ||
668 | } | 799 | } |
669 | break; | ||
670 | case 2: | ||
671 | switch ((config0 & MIPS_CONF_AR) >> 10) { | ||
672 | case 0: | ||
673 | c->isa_level = MIPS_CPU_ISA_M64R1; | ||
674 | break; | ||
675 | case 1: | ||
676 | c->isa_level = MIPS_CPU_ISA_M64R2; | ||
677 | break; | ||
678 | default: | ||
679 | goto unknown; | ||
680 | } | ||
681 | break; | ||
682 | default: | ||
683 | goto unknown; | ||
684 | } | ||
685 | |||
686 | return config0 & MIPS_CONF_M; | ||
687 | |||
688 | unknown: | ||
689 | panic(unknown_isa, config0); | ||
690 | } | ||
691 | 800 | ||
692 | static inline unsigned int decode_config1(struct cpuinfo_mips *c) | 801 | break; |
693 | { | ||
694 | unsigned int config1; | ||
695 | |||
696 | config1 = read_c0_config1(); | ||
697 | |||
698 | if (config1 & MIPS_CONF1_MD) | ||
699 | c->ases |= MIPS_ASE_MDMX; | ||
700 | if (config1 & MIPS_CONF1_WR) | ||
701 | c->options |= MIPS_CPU_WATCH; | ||
702 | if (config1 & MIPS_CONF1_CA) | ||
703 | c->ases |= MIPS_ASE_MIPS16; | ||
704 | if (config1 & MIPS_CONF1_EP) | ||
705 | c->options |= MIPS_CPU_EJTAG; | ||
706 | if (config1 & MIPS_CONF1_FP) { | ||
707 | c->options |= MIPS_CPU_FPU; | ||
708 | c->options |= MIPS_CPU_32FPR; | ||
709 | } | 802 | } |
710 | if (cpu_has_tlb) | ||
711 | c->tlbsize = ((config1 & MIPS_CONF1_TLBS) >> 25) + 1; | ||
712 | |||
713 | return config1 & MIPS_CONF_M; | ||
714 | } | ||
715 | |||
716 | static inline unsigned int decode_config2(struct cpuinfo_mips *c) | ||
717 | { | ||
718 | unsigned int config2; | ||
719 | |||
720 | config2 = read_c0_config2(); | ||
721 | |||
722 | if (config2 & MIPS_CONF2_SL) | ||
723 | c->scache.flags &= ~MIPS_CACHE_NOT_PRESENT; | ||
724 | |||
725 | return config2 & MIPS_CONF_M; | ||
726 | } | ||
727 | |||
728 | static inline unsigned int decode_config3(struct cpuinfo_mips *c) | ||
729 | { | ||
730 | unsigned int config3; | ||
731 | |||
732 | config3 = read_c0_config3(); | ||
733 | |||
734 | if (config3 & MIPS_CONF3_SM) | ||
735 | c->ases |= MIPS_ASE_SMARTMIPS; | ||
736 | if (config3 & MIPS_CONF3_DSP) | ||
737 | c->ases |= MIPS_ASE_DSP; | ||
738 | if (config3 & MIPS_CONF3_VINT) | ||
739 | c->options |= MIPS_CPU_VINT; | ||
740 | if (config3 & MIPS_CONF3_VEIC) | ||
741 | c->options |= MIPS_CPU_VEIC; | ||
742 | if (config3 & MIPS_CONF3_MT) | ||
743 | c->ases |= MIPS_ASE_MIPSMT; | ||
744 | if (config3 & MIPS_CONF3_ULRI) | ||
745 | c->options |= MIPS_CPU_ULRI; | ||
746 | |||
747 | return config3 & MIPS_CONF_M; | ||
748 | } | ||
749 | |||
750 | static inline unsigned int decode_config4(struct cpuinfo_mips *c) | ||
751 | { | ||
752 | unsigned int config4; | ||
753 | |||
754 | config4 = read_c0_config4(); | ||
755 | |||
756 | if ((config4 & MIPS_CONF4_MMUEXTDEF) == MIPS_CONF4_MMUEXTDEF_MMUSIZEEXT | ||
757 | && cpu_has_tlb) | ||
758 | c->tlbsize += (config4 & MIPS_CONF4_MMUSIZEEXT) * 0x40; | ||
759 | |||
760 | c->kscratch_mask = (config4 >> 16) & 0xff; | ||
761 | |||
762 | return config4 & MIPS_CONF_M; | ||
763 | } | ||
764 | |||
765 | static void __cpuinit decode_configs(struct cpuinfo_mips *c) | ||
766 | { | ||
767 | int ok; | ||
768 | |||
769 | /* MIPS32 or MIPS64 compliant CPU. */ | ||
770 | c->options = MIPS_CPU_4KEX | MIPS_CPU_4K_CACHE | MIPS_CPU_COUNTER | | ||
771 | MIPS_CPU_DIVEC | MIPS_CPU_LLSC | MIPS_CPU_MCHECK; | ||
772 | |||
773 | c->scache.flags = MIPS_CACHE_NOT_PRESENT; | ||
774 | |||
775 | ok = decode_config0(c); /* Read Config registers. */ | ||
776 | BUG_ON(!ok); /* Arch spec violation! */ | ||
777 | if (ok) | ||
778 | ok = decode_config1(c); | ||
779 | if (ok) | ||
780 | ok = decode_config2(c); | ||
781 | if (ok) | ||
782 | ok = decode_config3(c); | ||
783 | if (ok) | ||
784 | ok = decode_config4(c); | ||
785 | |||
786 | mips_probe_watch_registers(c); | ||
787 | |||
788 | if (cpu_has_mips_r2) | ||
789 | c->core = read_c0_ebase() & 0x3ff; | ||
790 | } | 803 | } |
791 | 804 | ||
792 | static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) | 805 | static inline void cpu_probe_mips(struct cpuinfo_mips *c, unsigned int cpu) |
diff --git a/arch/mips/kernel/perf_event_mipsxx.c b/arch/mips/kernel/perf_event_mipsxx.c index eb5e394a4650..2f28d3b55687 100644 --- a/arch/mips/kernel/perf_event_mipsxx.c +++ b/arch/mips/kernel/perf_event_mipsxx.c | |||
@@ -1559,6 +1559,11 @@ init_hw_perf_events(void) | |||
1559 | mipspmu.general_event_map = &mipsxxcore_event_map; | 1559 | mipspmu.general_event_map = &mipsxxcore_event_map; |
1560 | mipspmu.cache_event_map = &mipsxxcore_cache_map; | 1560 | mipspmu.cache_event_map = &mipsxxcore_cache_map; |
1561 | break; | 1561 | break; |
1562 | case CPU_LOONGSON1: | ||
1563 | mipspmu.name = "mips/loongson1"; | ||
1564 | mipspmu.general_event_map = &mipsxxcore_event_map; | ||
1565 | mipspmu.cache_event_map = &mipsxxcore_cache_map; | ||
1566 | break; | ||
1562 | case CPU_CAVIUM_OCTEON: | 1567 | case CPU_CAVIUM_OCTEON: |
1563 | case CPU_CAVIUM_OCTEON_PLUS: | 1568 | case CPU_CAVIUM_OCTEON_PLUS: |
1564 | case CPU_CAVIUM_OCTEON2: | 1569 | case CPU_CAVIUM_OCTEON2: |
diff --git a/arch/mips/kernel/prom.c b/arch/mips/kernel/prom.c index f11b2bbb826d..028f6f837ef9 100644 --- a/arch/mips/kernel/prom.c +++ b/arch/mips/kernel/prom.c | |||
@@ -35,16 +35,6 @@ void __init early_init_dt_add_memory_arch(u64 base, u64 size) | |||
35 | return add_memory_region(base, size, BOOT_MEM_RAM); | 35 | return add_memory_region(base, size, BOOT_MEM_RAM); |
36 | } | 36 | } |
37 | 37 | ||
38 | int __init reserve_mem_mach(unsigned long addr, unsigned long size) | ||
39 | { | ||
40 | return reserve_bootmem(addr, size, BOOTMEM_DEFAULT); | ||
41 | } | ||
42 | |||
43 | void __init free_mem_mach(unsigned long addr, unsigned long size) | ||
44 | { | ||
45 | return free_bootmem(addr, size); | ||
46 | } | ||
47 | |||
48 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) | 38 | void * __init early_init_dt_alloc_memory_arch(u64 size, u64 align) |
49 | { | 39 | { |
50 | return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); | 40 | return __alloc_bootmem(size, align, __pa(MAX_DMA_ADDRESS)); |
@@ -77,25 +67,6 @@ void __init early_init_devtree(void *params) | |||
77 | of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL); | 67 | of_scan_flat_dt(early_init_dt_scan_memory_arch, NULL); |
78 | } | 68 | } |
79 | 69 | ||
80 | void __init device_tree_init(void) | ||
81 | { | ||
82 | unsigned long base, size; | ||
83 | |||
84 | if (!initial_boot_params) | ||
85 | return; | ||
86 | |||
87 | base = virt_to_phys((void *)initial_boot_params); | ||
88 | size = be32_to_cpu(initial_boot_params->totalsize); | ||
89 | |||
90 | /* Before we do anything, lets reserve the dt blob */ | ||
91 | reserve_mem_mach(base, size); | ||
92 | |||
93 | unflatten_device_tree(); | ||
94 | |||
95 | /* free the space reserved for the dt blob */ | ||
96 | free_mem_mach(base, size); | ||
97 | } | ||
98 | |||
99 | void __init __dt_setup_arch(struct boot_param_header *bph) | 70 | void __init __dt_setup_arch(struct boot_param_header *bph) |
100 | { | 71 | { |
101 | if (be32_to_cpu(bph->magic) != OF_DT_HEADER) { | 72 | if (be32_to_cpu(bph->magic) != OF_DT_HEADER) { |
diff --git a/arch/mips/kernel/smp.c b/arch/mips/kernel/smp.c index 1268392f1d27..31637d8c8738 100644 --- a/arch/mips/kernel/smp.c +++ b/arch/mips/kernel/smp.c | |||
@@ -102,7 +102,9 @@ asmlinkage __cpuinit void start_secondary(void) | |||
102 | 102 | ||
103 | #ifdef CONFIG_MIPS_MT_SMTC | 103 | #ifdef CONFIG_MIPS_MT_SMTC |
104 | /* Only do cpu_probe for first TC of CPU */ | 104 | /* Only do cpu_probe for first TC of CPU */ |
105 | if ((read_c0_tcbind() & TCBIND_CURTC) == 0) | 105 | if ((read_c0_tcbind() & TCBIND_CURTC) != 0) |
106 | __cpu_name[smp_processor_id()] = __cpu_name[0]; | ||
107 | else | ||
106 | #endif /* CONFIG_MIPS_MT_SMTC */ | 108 | #endif /* CONFIG_MIPS_MT_SMTC */ |
107 | cpu_probe(); | 109 | cpu_probe(); |
108 | cpu_report(); | 110 | cpu_report(); |
diff --git a/arch/mips/kernel/smtc.c b/arch/mips/kernel/smtc.c index 15b5f3cfd20c..1d47843d3cc0 100644 --- a/arch/mips/kernel/smtc.c +++ b/arch/mips/kernel/smtc.c | |||
@@ -86,6 +86,13 @@ struct smtc_ipi_q IPIQ[NR_CPUS]; | |||
86 | static struct smtc_ipi_q freeIPIq; | 86 | static struct smtc_ipi_q freeIPIq; |
87 | 87 | ||
88 | 88 | ||
89 | /* | ||
90 | * Number of FPU contexts for each VPE | ||
91 | */ | ||
92 | |||
93 | static int smtc_nconf1[MAX_SMTC_VPES]; | ||
94 | |||
95 | |||
89 | /* Forward declarations */ | 96 | /* Forward declarations */ |
90 | 97 | ||
91 | void ipi_decode(struct smtc_ipi *); | 98 | void ipi_decode(struct smtc_ipi *); |
@@ -174,9 +181,9 @@ static int __init tintq(char *str) | |||
174 | 181 | ||
175 | __setup("tintq=", tintq); | 182 | __setup("tintq=", tintq); |
176 | 183 | ||
177 | static int imstuckcount[2][8]; | 184 | static int imstuckcount[MAX_SMTC_VPES][8]; |
178 | /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ | 185 | /* vpemask represents IM/IE bits of per-VPE Status registers, low-to-high */ |
179 | static int vpemask[2][8] = { | 186 | static int vpemask[MAX_SMTC_VPES][8] = { |
180 | {0, 0, 1, 0, 0, 0, 0, 1}, | 187 | {0, 0, 1, 0, 0, 0, 0, 1}, |
181 | {0, 0, 0, 0, 0, 0, 0, 1} | 188 | {0, 0, 0, 0, 0, 0, 0, 1} |
182 | }; | 189 | }; |
@@ -331,6 +338,22 @@ int __init smtc_build_cpu_map(int start_cpu_slot) | |||
331 | 338 | ||
332 | static void smtc_tc_setup(int vpe, int tc, int cpu) | 339 | static void smtc_tc_setup(int vpe, int tc, int cpu) |
333 | { | 340 | { |
341 | static int cp1contexts[MAX_SMTC_VPES]; | ||
342 | |||
343 | /* | ||
344 | * Make a local copy of the available FPU contexts in order | ||
345 | * to keep track of TCs that can have one. | ||
346 | */ | ||
347 | if (tc == 1) | ||
348 | { | ||
349 | /* | ||
350 | * FIXME: Multi-core SMTC hasn't been tested and the | ||
351 | * maximum number of VPEs may change. | ||
352 | */ | ||
353 | cp1contexts[0] = smtc_nconf1[0] - 1; | ||
354 | cp1contexts[1] = smtc_nconf1[1]; | ||
355 | } | ||
356 | |||
334 | settc(tc); | 357 | settc(tc); |
335 | write_tc_c0_tchalt(TCHALT_H); | 358 | write_tc_c0_tchalt(TCHALT_H); |
336 | mips_ihb(); | 359 | mips_ihb(); |
@@ -343,22 +366,29 @@ static void smtc_tc_setup(int vpe, int tc, int cpu) | |||
343 | * an active IPI queue. | 366 | * an active IPI queue. |
344 | */ | 367 | */ |
345 | write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); | 368 | write_tc_c0_tccontext((sizeof(struct smtc_ipi_q) * cpu) << 16); |
346 | /* Bind tc to vpe */ | 369 | |
370 | /* Bind TC to VPE. */ | ||
347 | write_tc_c0_tcbind(vpe); | 371 | write_tc_c0_tcbind(vpe); |
372 | |||
348 | /* In general, all TCs should have the same cpu_data indications. */ | 373 | /* In general, all TCs should have the same cpu_data indications. */ |
349 | memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); | 374 | memcpy(&cpu_data[cpu], &cpu_data[0], sizeof(struct cpuinfo_mips)); |
350 | /* For 34Kf, start with TC/CPU 0 as sole owner of single FPU context */ | 375 | |
351 | if (cpu_data[0].cputype == CPU_34K || | 376 | /* Check to see if there is a FPU context available for this TC. */ |
352 | cpu_data[0].cputype == CPU_1004K) | 377 | if (!cp1contexts[vpe]) |
353 | cpu_data[cpu].options &= ~MIPS_CPU_FPU; | 378 | cpu_data[cpu].options &= ~MIPS_CPU_FPU; |
379 | else | ||
380 | cp1contexts[vpe]--; | ||
381 | |||
382 | /* Store the TC and VPE into the cpu_data structure. */ | ||
354 | cpu_data[cpu].vpe_id = vpe; | 383 | cpu_data[cpu].vpe_id = vpe; |
355 | cpu_data[cpu].tc_id = tc; | 384 | cpu_data[cpu].tc_id = tc; |
356 | /* Multi-core SMTC hasn't been tested, but be prepared */ | 385 | |
386 | /* FIXME: Multi-core SMTC hasn't been tested, but be prepared. */ | ||
357 | cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; | 387 | cpu_data[cpu].core = (read_vpe_c0_ebase() >> 1) & 0xff; |
358 | } | 388 | } |
359 | 389 | ||
360 | /* | 390 | /* |
361 | * Tweak to get Count registes in as close a sync as possible. The | 391 | * Tweak to get Count registers synced as closely as possible. The |
362 | * value seems good for 34K-class cores. | 392 | * value seems good for 34K-class cores. |
363 | */ | 393 | */ |
364 | 394 | ||
@@ -466,6 +496,24 @@ void smtc_prepare_cpus(int cpus) | |||
466 | smtc_configure_tlb(); | 496 | smtc_configure_tlb(); |
467 | 497 | ||
468 | for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { | 498 | for (tc = 0, vpe = 0 ; (vpe < nvpe) && (tc < ntc) ; vpe++) { |
499 | /* Get number of CP1 contexts for each VPE. */ | ||
500 | if (tc == 0) | ||
501 | { | ||
502 | /* | ||
503 | * Do not call settc() for TC0 or the FPU context | ||
504 | * value will be incorrect. Besides, we know that | ||
505 | * we are TC0 anyway. | ||
506 | */ | ||
507 | smtc_nconf1[0] = ((read_vpe_c0_vpeconf1() & | ||
508 | VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT); | ||
509 | if (nvpe == 2) | ||
510 | { | ||
511 | settc(1); | ||
512 | smtc_nconf1[1] = ((read_vpe_c0_vpeconf1() & | ||
513 | VPECONF1_NCP1) >> VPECONF1_NCP1_SHIFT); | ||
514 | settc(0); | ||
515 | } | ||
516 | } | ||
469 | if (tcpervpe[vpe] == 0) | 517 | if (tcpervpe[vpe] == 0) |
470 | continue; | 518 | continue; |
471 | if (vpe != 0) | 519 | if (vpe != 0) |
@@ -479,6 +527,18 @@ void smtc_prepare_cpus(int cpus) | |||
479 | */ | 527 | */ |
480 | if (tc != 0) { | 528 | if (tc != 0) { |
481 | smtc_tc_setup(vpe, tc, cpu); | 529 | smtc_tc_setup(vpe, tc, cpu); |
530 | if (vpe != 0) { | ||
531 | /* | ||
532 | * Set MVP bit (possibly again). Do it | ||
533 | * here to catch CPUs that have no TCs | ||
534 | * bound to the VPE at reset. In that | ||
535 | * case, a TC must be bound to the VPE | ||
536 | * before we can set VPEControl[MVP] | ||
537 | */ | ||
538 | write_vpe_c0_vpeconf0( | ||
539 | read_vpe_c0_vpeconf0() | | ||
540 | VPECONF0_MVP); | ||
541 | } | ||
482 | cpu++; | 542 | cpu++; |
483 | } | 543 | } |
484 | printk(" %d", tc); | 544 | printk(" %d", tc); |
diff --git a/arch/mips/kernel/traps.c b/arch/mips/kernel/traps.c index c3c293543703..9be3df1fa8a4 100644 --- a/arch/mips/kernel/traps.c +++ b/arch/mips/kernel/traps.c | |||
@@ -1253,6 +1253,7 @@ static inline void parity_protection_init(void) | |||
1253 | 1253 | ||
1254 | case CPU_5KC: | 1254 | case CPU_5KC: |
1255 | case CPU_5KE: | 1255 | case CPU_5KE: |
1256 | case CPU_LOONGSON1: | ||
1256 | write_c0_ecc(0x80000000); | 1257 | write_c0_ecc(0x80000000); |
1257 | back_to_back_c0_hazard(); | 1258 | back_to_back_c0_hazard(); |
1258 | /* Set the PE bit (bit 31) in the c0_errctl register. */ | 1259 | /* Set the PE bit (bit 31) in the c0_errctl register. */ |