|
@@ -35,6 +35,8 @@
|
|
|
#include <asm/spu.h>
|
|
|
#include <asm/spu_priv1.h>
|
|
|
#include <asm/xmon.h>
|
|
|
+#include <asm/prom.h>
|
|
|
+#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);
|