From 3ad216cae837d90415c605e1149e6fd88f51c973 Mon Sep 17 00:00:00 2001 From: Arnd Bergmann Date: Fri, 20 Jul 2007 21:39:46 +0200 Subject: [CELL] cell: add hardcoded spu vicinity information for QS20 This patch allows the use of spu affinity on QS20, whose original FW does not provide affinity information. This is done through two hardcoded arrays, and by reading the reg property from each spu. Signed-off-by: Andre Detsch Signed-off-by: Arnd Bergmann --- arch/powerpc/platforms/cell/spu_base.c | 55 +++++++++++++++++++++++++++++++++- 1 file changed, 54 insertions(+), 1 deletion(-) (limited to 'arch/powerpc/platforms/cell') diff --git a/arch/powerpc/platforms/cell/spu_base.c b/arch/powerpc/platforms/cell/spu_base.c index 0fc2e12a3c8..75b5af0a7e2 100644 --- a/arch/powerpc/platforms/cell/spu_base.c +++ b/arch/powerpc/platforms/cell/spu_base.c @@ -35,6 +35,8 @@ #include #include #include +#include +#include "spu_priv1_mmio.h" const struct spu_management_ops *spu_management_ops; EXPORT_SYMBOL_GPL(spu_management_ops); @@ -657,6 +659,52 @@ static SYSDEV_ATTR(stat, 0644, spu_stat_show, NULL); struct cbe_spu_info cbe_spu_info[MAX_NUMNODES]; EXPORT_SYMBOL_GPL(cbe_spu_info); +/* Hardcoded affinity idxs for QS20 */ +#define SPES_PER_BE 8 +static int QS20_reg_idxs[SPES_PER_BE] = { 0, 2, 4, 6, 7, 5, 3, 1 }; +static int QS20_reg_memory[SPES_PER_BE] = { 1, 1, 0, 0, 0, 0, 0, 0 }; + +static struct spu *spu_lookup_reg(int node, u32 reg) +{ + struct spu *spu; + + list_for_each_entry(spu, &cbe_spu_info[node].spus, cbe_list) { + if (*(u32 *)get_property(spu_devnode(spu), "reg", NULL) == reg) + return spu; + } + return NULL; +} + +static void init_aff_QS20_harcoded(void) +{ + int node, i; + struct spu *last_spu, *spu; + u32 reg; + + for (node = 0; node < MAX_NUMNODES; node++) { + last_spu = NULL; + for (i = 0; i < SPES_PER_BE; i++) { + reg = QS20_reg_idxs[i]; + spu = spu_lookup_reg(node, reg); + if (!spu) + continue; + spu->has_mem_affinity = QS20_reg_memory[reg]; + if (last_spu) + list_add_tail(&spu->aff_list, + &last_spu->aff_list); + last_spu = spu; + } + } +} + +static int of_has_vicinity(void) +{ + struct spu* spu; + + spu = list_entry(cbe_spu_info[0].spus.next, struct spu, cbe_list); + return of_find_property(spu_devnode(spu), "vicinity", NULL) != NULL; +} + static int __init init_spu_base(void) { int i, ret = 0; @@ -698,12 +746,17 @@ static int __init init_spu_base(void) crash_register_spus(&spu_full_list); spu_add_sysdev_attr(&attr_stat); + if (!of_has_vicinity()) { + long root = of_get_flat_dt_root(); + if (of_flat_dt_is_compatible(root, "IBM,CPBW-1.0")) + init_aff_QS20_harcoded(); + } + return 0; out_unregister_sysdev_class: sysdev_class_unregister(&spu_sysdev_class); out: - return ret; } module_init(init_spu_base); -- cgit v1.2.3