diff options
Diffstat (limited to 'arch')
-rw-r--r-- | arch/powerpc/platforms/cell/spu_base.c | 55 |
1 files changed, 54 insertions, 1 deletions
diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 0fc2e12a3c85..75b5af0a7e21 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c | |||
@@ -35,6 +35,8 @@ | |||
35 | #include <asm/spu.h> | 35 | #include <asm/spu.h> |
36 | #include <asm/spu_priv1.h> | 36 | #include <asm/spu_priv1.h> |
37 | #include <asm/xmon.h> | 37 | #include <asm/xmon.h> |
38 | #include <asm/prom.h> | ||
39 | #include "spu_priv1_mmio.h" | ||
38 | 40 | ||
39 | const struct spu_management_ops *spu_management_ops; | 41 | const struct spu_management_ops *spu_management_ops; |
40 | EXPORT_SYMBOL_GPL(spu_management_ops); | 42 | EXPORT_SYMBOL_GPL(spu_management_ops); |
@@ -657,6 +659,52 @@ static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL); | |||
657 | struct cbe_spu_info cbe_spu_info[MAX_NUMNODES]; | 659 | struct cbe_spu_info cbe_spu_info[MAX_NUMNODES]; |
658 | EXPORT_SYMBOL_GPL(cbe_spu_info); | 660 | EXPORT_SYMBOL_GPL(cbe_spu_info); |
659 | 661 | ||
662 | /* Hardcoded affinity idxs for QS20 */ | ||
663 | #define SPES_PER_BE 8 | ||
664 | static int QS20_reg_idxs[SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 }; | ||
665 | static int QS20_reg_memory[SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 }; | ||
666 | |||
667 | static struct spu *spu_lookup_reg(int node, u32 reg) | ||
668 | { | ||
669 | struct spu *spu; | ||
670 | |||
671 | list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { | ||
672 | if (*(u32 *)get_property(spu_devnode(spu), "reg", NULL) == reg) | ||
673 | return spu; | ||
674 | } | ||
675 | return NULL; | ||
676 | } | ||
677 | |||
678 | static void init_aff_QS20_harcoded(void) | ||
679 | { | ||
680 | int node, i; | ||
681 | struct spu *last_spu, *spu; | ||
682 | u32 reg; | ||
683 | |||
684 | for (node = 0; node < MAX_NUMNODES; node++) { | ||
685 | last_spu = NULL; | ||
686 | for (i = 0; i < SPES_PER_BE; i++) { | ||
687 | reg = QS20_reg_idxs[i]; | ||
688 | spu = spu_lookup_reg(node, reg); | ||
689 | if (!spu) | ||
690 | continue; | ||
691 | spu->has_mem_affinity = QS20_reg_memory[reg]; | ||
692 | if (last_spu) | ||
693 | list_add_tail(&spu->aff_list, | ||
694 | &last_spu->aff_list); | ||
695 | last_spu = spu; | ||
696 | } | ||
697 | } | ||
698 | } | ||
699 | |||
700 | static int of_has_vicinity(void) | ||
701 | { | ||
702 | struct spu* spu; | ||
703 | |||
704 | spu = list_entry(cbe_spu_info[0].spus.next, struct spu, cbe_list); | ||
705 | return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL; | ||
706 | } | ||
707 | |||
660 | static int __init init_spu_base(void) | 708 | static int __init init_spu_base(void) |
661 | { | 709 | { |
662 | int i, ret = 0; | 710 | int i, ret = 0; |
@@ -698,12 +746,17 @@ static int __init init_spu_base(void) | |||
698 | crash_register_spus(&spu_full_list); | 746 | crash_register_spus(&spu_full_list); |
699 | spu_add_sysdev_attr(&attr_stat); | 747 | spu_add_sysdev_attr(&attr_stat); |
700 | 748 | ||
749 | if (!of_has_vicinity()) { | ||
750 | long root = of_get_flat_dt_root(); | ||
751 | if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) | ||
752 | init_aff_QS20_harcoded(); | ||
753 | } | ||
754 | |||
701 | return 0; | 755 | return 0; |
702 | 756 | ||
703 | out_unregister_sysdev_class: | 757 | out_unregister_sysdev_class: |
704 | sysdev_class_unregister(&spu_sysdev_class); | 758 | sysdev_class_unregister(&spu_sysdev_class); |
705 | out: | 759 | out: |
706 | |||
707 | return ret; | 760 | return ret; |
708 | } | 761 | } |
709 | module_init(init_spu_base); | 762 | module_init(init_spu_base); |