]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - arch/powerpc/platforms/ps3/spu.c
powerpc/ps3: Rework htab code to remove ioremap
[linux-2.6-omap-h63xx.git] / arch / powerpc / platforms / ps3 / spu.c
index a397e4e17c13ca93230f2a33977b4627170c3f21..d135cef9ed6a91d97eba9a0500213cb8d460df86 100644 (file)
@@ -27,7 +27,9 @@
 #include <asm/spu.h>
 #include <asm/spu_priv1.h>
 #include <asm/lv1call.h>
+#include <asm/ps3.h>
 
+#include "../cell/spufs/spufs.h"
 #include "platform.h"
 
 /* spu_management_ops */
@@ -139,6 +141,12 @@ static void _dump_areas(unsigned int spe_id, unsigned long priv2,
        pr_debug("%s:%d: shadow:  %lxh\n", func, line, shadow);
 }
 
+inline u64 ps3_get_spe_id(void *arg)
+{
+       return spu_pdata(arg)->spe_id;
+}
+EXPORT_SYMBOL_GPL(ps3_get_spe_id);
+
 static unsigned long get_vas_id(void)
 {
        unsigned long id;
@@ -182,15 +190,18 @@ static int __init setup_areas(struct spu *spu)
 {
        struct table {char* name; unsigned long addr; unsigned long size;};
 
-       spu_pdata(spu)->shadow = __ioremap(
-               spu_pdata(spu)->shadow_addr, sizeof(struct spe_shadow),
-               PAGE_READONLY | _PAGE_NO_CACHE | _PAGE_GUARDED);
+       spu_pdata(spu)->shadow = ioremap_flags(spu_pdata(spu)->shadow_addr,
+                                              sizeof(struct spe_shadow),
+                                              pgprot_val(PAGE_READONLY) |
+                                              _PAGE_NO_CACHE);
        if (!spu_pdata(spu)->shadow) {
                pr_debug("%s:%d: ioremap shadow failed\n", __func__, __LINE__);
                goto fail_ioremap;
        }
 
-       spu->local_store = ioremap(spu->local_store_phys, LS_SIZE);
+       spu->local_store = (__force void *)ioremap_flags(spu->local_store_phys,
+               LS_SIZE, _PAGE_NO_CACHE);
+
        if (!spu->local_store) {
                pr_debug("%s:%d: ioremap local_store failed\n",
                        __func__, __LINE__);
@@ -199,6 +210,7 @@ static int __init setup_areas(struct spu *spu)
 
        spu->problem = ioremap(spu->problem_phys,
                sizeof(struct spu_problem));
+
        if (!spu->problem) {
                pr_debug("%s:%d: ioremap problem failed\n", __func__, __LINE__);
                goto fail_ioremap;
@@ -206,6 +218,7 @@ static int __init setup_areas(struct spu *spu)
 
        spu->priv2 = ioremap(spu_pdata(spu)->priv2_addr,
                sizeof(struct spu_priv2));
+
        if (!spu->priv2) {
                pr_debug("%s:%d: ioremap priv2 failed\n", __func__, __LINE__);
                goto fail_ioremap;
@@ -230,19 +243,19 @@ static int __init setup_interrupts(struct spu *spu)
 {
        int result;
 
-       result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+       result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
                0, &spu->irqs[0]);
 
        if (result)
                goto fail_alloc_0;
 
-       result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+       result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
                1, &spu->irqs[1]);
 
        if (result)
                goto fail_alloc_1;
 
-       result = ps3_alloc_spe_irq(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
+       result = ps3_spe_irq_setup(PS3_BINDING_CPU_ANY, spu_pdata(spu)->spe_id,
                2, &spu->irqs[2]);
 
        if (result)
@@ -251,9 +264,9 @@ static int __init setup_interrupts(struct spu *spu)
        return result;
 
 fail_alloc_2:
-       ps3_free_spe_irq(spu->irqs[1]);
+       ps3_spe_irq_destroy(spu->irqs[1]);
 fail_alloc_1:
-       ps3_free_spe_irq(spu->irqs[0]);
+       ps3_spe_irq_destroy(spu->irqs[0]);
 fail_alloc_0:
        spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
        return result;
@@ -301,9 +314,9 @@ static int ps3_destroy_spu(struct spu *spu)
        result = lv1_disable_logical_spe(spu_pdata(spu)->spe_id, 0);
        BUG_ON(result);
 
-       ps3_free_spe_irq(spu->irqs[2]);
-       ps3_free_spe_irq(spu->irqs[1]);
-       ps3_free_spe_irq(spu->irqs[0]);
+       ps3_spe_irq_destroy(spu->irqs[2]);
+       ps3_spe_irq_destroy(spu->irqs[1]);
+       ps3_spe_irq_destroy(spu->irqs[0]);
 
        spu->irqs[0] = spu->irqs[1] = spu->irqs[2] = NO_IRQ;
 
@@ -400,17 +413,49 @@ static int __init ps3_enumerate_spus(int (*fn)(void *data))
                }
        }
 
-       if (result)
+       if (result) {
                printk(KERN_WARNING "%s:%d: Error initializing spus\n",
                        __func__, __LINE__);
+               return result;
+       }
 
-       return result;
+       return num_resource_id;
+}
+
+static int ps3_init_affinity(void)
+{
+       return 0;
+}
+
+/**
+ * ps3_enable_spu - Enable SPU run control.
+ *
+ * An outstanding enhancement for the PS3 would be to add a guard to check
+ * for incorrect access to the spu problem state when the spu context is
+ * disabled.  This check could be implemented with a flag added to the spu
+ * context that would inhibit mapping problem state pages, and a routine
+ * to unmap spu problem state pages.  When the spu is enabled with
+ * ps3_enable_spu() the flag would be set allowing pages to be mapped,
+ * and when the spu is disabled with ps3_disable_spu() the flag would be
+ * cleared and the mapped problem state pages would be unmapped.
+ */
+
+static void ps3_enable_spu(struct spu_context *ctx)
+{
+}
+
+static void ps3_disable_spu(struct spu_context *ctx)
+{
+       ctx->ops->runcntl_stop(ctx);
 }
 
 const struct spu_management_ops spu_management_ps3_ops = {
        .enumerate_spus = ps3_enumerate_spus,
        .create_spu = ps3_create_spu,
        .destroy_spu = ps3_destroy_spu,
+       .enable_spu = ps3_enable_spu,
+       .disable_spu = ps3_disable_spu,
+       .init_affinity = ps3_init_affinity,
 };
 
 /* spu_priv1_ops */