aboutsummaryrefslogtreecommitdiffstats
path: root/arch
diff options
context:
space:
mode:
Diffstat (limited to 'arch')
-rw-r--r--arch/powerpc/platforms/cell/spu_base.c55
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
39const struct spu_management_ops *spu_management_ops; 41const struct spu_management_ops *spu_management_ops;
40EXPORT_SYMBOL_GPL(spu_management_ops); 42EXPORT_SYMBOL_GPL(spu_management_ops);
@@ -657,6 +659,52 @@ static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL);
657struct cbe_spu_info cbe_spu_info[MAX_NUMNODES]; 659struct cbe_spu_info cbe_spu_info[MAX_NUMNODES];
658EXPORT_SYMBOL_GPL(cbe_spu_info); 660EXPORT_SYMBOL_GPL(cbe_spu_info);
659 661
662/* Hardcoded affinity idxs for QS20 */
663#define SPES_PER_BE 8
664static int QS20_reg_idxs[SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 };
665static int QS20_reg_memory[SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 };
666
667static 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
678static 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
700static 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
660static int __init init_spu_base(void) 708static 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}
709module_init(init_spu_base); 762module_init(init_spu_base);