Begin consolidation of of_device.h
[safe/jmp/linux-2.6] / include / asm-powerpc / spu.h
index ee337e3..eedc828 100644 (file)
 #define _SPU_H
 #ifdef __KERNEL__
 
-#include <linux/config.h>
-#include <linux/kref.h>
 #include <linux/workqueue.h>
+#include <linux/sysdev.h>
 
-#define LS_ORDER (6)           /* 256 kb */
-
-#define LS_SIZE (PAGE_SIZE << LS_ORDER)
+#define LS_SIZE (256 * 1024)
 #define LS_ADDR_MASK (LS_SIZE - 1)
 
 #define MFC_PUT_CMD             0x20
 #define MFC_MULTI_SRC_EVENT                 0x00001000
 
 /* Flags indicating progress during context switch. */
-#define SPU_CONTEXT_SWITCH_PENDING_nr  0UL
-#define SPU_CONTEXT_SWITCH_ACTIVE_nr   1UL
-#define SPU_CONTEXT_SWITCH_PENDING     (1UL << SPU_CONTEXT_SWITCH_PENDING_nr)
-#define SPU_CONTEXT_SWITCH_ACTIVE      (1UL << SPU_CONTEXT_SWITCH_ACTIVE_nr)
+#define SPU_CONTEXT_SWITCH_PENDING     0UL
+#define SPU_CONTEXT_SWITCH_ACTIVE      1UL
 
 struct spu_context;
 struct spu_runqueue;
+struct device_node;
+
+enum spu_utilization_state {
+       SPU_UTIL_SYSTEM,
+       SPU_UTIL_USER,
+       SPU_UTIL_IOWAIT,
+       SPU_UTIL_IDLE,
+       SPU_UTIL_MAX
+};
 
 struct spu {
-       char *name;
+       const char *name;
        unsigned long local_store_phys;
        u8 *local_store;
+       unsigned long problem_phys;
        struct spu_problem __iomem *problem;
-       struct spu_priv1 __iomem *priv1;
        struct spu_priv2 __iomem *priv2;
        struct list_head list;
        struct list_head sched_list;
+       struct list_head full_list;
        int number;
-       u32 isrc;
+       unsigned int irqs[3];
        u32 node;
        u64 flags;
        u64 dar;
        u64 dsisr;
-       struct kref kref;
        size_t ls_size;
        unsigned int slb_replace;
        struct mm_struct *mm;
@@ -133,25 +137,73 @@ struct spu {
        struct spu_runqueue *rq;
        unsigned long long timestamp;
        pid_t pid;
-       int prio;
        int class_0_pending;
        spinlock_t register_lock;
 
-       u32 stop_code;
        void (* wbox_callback)(struct spu *spu);
        void (* ibox_callback)(struct spu *spu);
        void (* stop_callback)(struct spu *spu);
+       void (* mfc_callback)(struct spu *spu);
+       void (* dma_callback)(struct spu *spu, int type);
 
        char irq_c0[8];
        char irq_c1[8];
        char irq_c2[8];
+
+       u64 spe_id;
+
+       void* pdata; /* platform private data */
+
+       /* of based platforms only */
+       struct device_node *devnode;
+
+       /* native only */
+       struct spu_priv1 __iomem *priv1;
+
+       /* beat only */
+       u64 shadow_int_mask_RW[3];
+
+       struct sys_device sysdev;
+
+       struct {
+               /* protected by interrupt reentrancy */
+               enum spu_utilization_state utilization_state;
+               unsigned long tstamp;           /* time of last ctx switch */
+               unsigned long times[SPU_UTIL_MAX];
+               unsigned long long vol_ctx_switch;
+               unsigned long long invol_ctx_switch;
+               unsigned long long min_flt;
+               unsigned long long maj_flt;
+               unsigned long long hash_flt;
+               unsigned long long slb_flt;
+               unsigned long long class2_intr;
+               unsigned long long libassist;
+       } stats;
 };
 
 struct spu *spu_alloc(void);
+struct spu *spu_alloc_node(int node);
 void spu_free(struct spu *spu);
 int spu_irq_class_0_bottom(struct spu *spu);
 int spu_irq_class_1_bottom(struct spu *spu);
+void spu_irq_setaffinity(struct spu *spu, int cpu);
+
+extern void spu_invalidate_slbs(struct spu *spu);
+extern void spu_associate_mm(struct spu *spu, struct mm_struct *mm);
+
+/* Calls from the memory management to the SPU */
+struct mm_struct;
+extern void spu_flush_all_slbs(struct mm_struct *mm);
 
+/* system callbacks from the SPU */
+struct spu_syscall_block {
+       u64 nr_ret;
+       u64 parm[6];
+};
+extern long spu_sys_callback(struct spu_syscall_block *s);
+
+/* syscalls implemented in spufs */
+struct file;
 extern struct spufs_calls {
        asmlinkage long (*create_thread)(const char __user *name,
                                        unsigned int flags, mode_t mode);
@@ -160,6 +212,31 @@ extern struct spufs_calls {
        struct module *owner;
 } spufs_calls;
 
+/* coredump calls implemented in spufs */
+struct spu_coredump_calls {
+       asmlinkage int (*arch_notes_size)(void);
+       asmlinkage void (*arch_write_notes)(struct file *file);
+       struct module *owner;
+};
+
+/* return status from spu_run, same as in libspe */
+#define SPE_EVENT_DMA_ALIGNMENT                0x0008  /*A DMA alignment error */
+#define SPE_EVENT_SPE_ERROR            0x0010  /*An illegal instruction error*/
+#define SPE_EVENT_SPE_DATA_SEGMENT     0x0020  /*A DMA segmentation error    */
+#define SPE_EVENT_SPE_DATA_STORAGE     0x0040  /*A DMA storage error */
+#define SPE_EVENT_INVALID_DMA          0x0800  /* Invalid MFC DMA */
+
+/*
+ * Flags for sys_spu_create.
+ */
+#define SPU_CREATE_EVENTS_ENABLED      0x0001
+#define SPU_CREATE_GANG                        0x0002
+#define SPU_CREATE_NOSCHED             0x0004
+#define SPU_CREATE_ISOLATE             0x0008
+
+#define SPU_CREATE_FLAG_ALL            0x000f /* mask of all valid flags */
+
+
 #ifdef CONFIG_SPU_FS_MODULE
 int register_spu_syscalls(struct spufs_calls *calls);
 void unregister_spu_syscalls(struct spufs_calls *calls);
@@ -173,6 +250,34 @@ static inline void unregister_spu_syscalls(struct spufs_calls *calls)
 }
 #endif /* MODULE */
 
+int register_arch_coredump_calls(struct spu_coredump_calls *calls);
+void unregister_arch_coredump_calls(struct spu_coredump_calls *calls);
+
+int spu_add_sysdev_attr(struct sysdev_attribute *attr);
+void spu_remove_sysdev_attr(struct sysdev_attribute *attr);
+
+int spu_add_sysdev_attr_group(struct attribute_group *attrs);
+void spu_remove_sysdev_attr_group(struct attribute_group *attrs);
+
+
+/*
+ * Notifier blocks:
+ *
+ * oprofile can get notified when a context switch is performed
+ * on an spe. The notifer function that gets called is passed
+ * a pointer to the SPU structure as well as the object-id that
+ * identifies the binary running on that SPU now.
+ *
+ * For a context save, the object-id that is passed is zero,
+ * identifying that the kernel will run from that moment on.
+ *
+ * For a context restore, the object-id is the value written
+ * to object-id spufs file from user space and the notifer
+ * function can assume that spu->ctx is valid.
+ */
+struct notifier_block;
+int spu_switch_event_register(struct notifier_block * n);
+int spu_switch_event_unregister(struct notifier_block * n);
 
 /*
  * This defines the Local Store, Problem Area and Privlege Area of an SPU.
@@ -233,6 +338,7 @@ struct spu_problem {
        u32 spu_runcntl_RW;                                     /* 0x401c */
 #define SPU_RUNCNTL_STOP       0L
 #define SPU_RUNCNTL_RUNNABLE   1L
+#define SPU_RUNCNTL_ISOLATE    2L
        u8  pad_0x4020_0x4024[0x4];                             /* 0x4020 */
        u32 spu_status_R;                                       /* 0x4024 */
 #define SPU_STOP_STATUS_SHIFT           16
@@ -245,8 +351,8 @@ struct spu_problem {
 #define SPU_STATUS_INVALID_INSTR        0x20
 #define SPU_STATUS_INVALID_CH           0x40
 #define SPU_STATUS_ISOLATED_STATE       0x80
-#define SPU_STATUS_ISOLATED_LOAD_STAUTUS 0x200
-#define SPU_STATUS_ISOLATED_EXIT_STAUTUS 0x400
+#define SPU_STATUS_ISOLATED_LOAD_STATUS 0x200
+#define SPU_STATUS_ISOLATED_EXIT_STATUS 0x400
        u8  pad_0x4028_0x402c[0x4];                             /* 0x4028 */
        u32 spu_spe_R;                                          /* 0x402c */
        u8  pad_0x4030_0x4034[0x4];                             /* 0x4030 */
@@ -365,6 +471,7 @@ struct spu_priv1 {
 #define MFC_STATE1_PROBLEM_STATE_MASK          0x08ull
 #define MFC_STATE1_RELOCATE_MASK               0x10ull
 #define MFC_STATE1_MASTER_RUN_CONTROL_MASK     0x20ull
+#define MFC_STATE1_TABLE_SEARCH_MASK           0x40ull
        u64 mfc_lpid_RW;                                        /* 0x008 */
        u64 spu_idr_RW;                                         /* 0x010 */
        u64 mfc_vr_RO;                                          /* 0x018 */
@@ -379,27 +486,22 @@ struct spu_priv1 {
 #define SPU_GET_REVISION_BITS(vr)      (vr & SPU_REVISION_BITS)
        u8  pad_0x28_0x100[0x100 - 0x28];                       /* 0x28 */
 
-
        /* Interrupt Area */
-       u64 int_mask_class0_RW;                                 /* 0x100 */
+       u64 int_mask_RW[3];                                     /* 0x100 */
 #define CLASS0_ENABLE_DMA_ALIGNMENT_INTR               0x1L
 #define CLASS0_ENABLE_INVALID_DMA_COMMAND_INTR         0x2L
 #define CLASS0_ENABLE_SPU_ERROR_INTR                   0x4L
 #define CLASS0_ENABLE_MFC_FIR_INTR                     0x8L
-       u64 int_mask_class1_RW;                                 /* 0x108 */
 #define CLASS1_ENABLE_SEGMENT_FAULT_INTR               0x1L
 #define CLASS1_ENABLE_STORAGE_FAULT_INTR               0x2L
 #define CLASS1_ENABLE_LS_COMPARE_SUSPEND_ON_GET_INTR   0x4L
 #define CLASS1_ENABLE_LS_COMPARE_SUSPEND_ON_PUT_INTR   0x8L
-       u64 int_mask_class2_RW;                                 /* 0x110 */
 #define CLASS2_ENABLE_MAILBOX_INTR                     0x1L
 #define CLASS2_ENABLE_SPU_STOP_INTR                    0x2L
 #define CLASS2_ENABLE_SPU_HALT_INTR                    0x4L
 #define CLASS2_ENABLE_SPU_DMA_TAG_GROUP_COMPLETE_INTR  0x8L
        u8  pad_0x118_0x140[0x28];                              /* 0x118 */
-       u64 int_stat_class0_RW;                                 /* 0x140 */
-       u64 int_stat_class1_RW;                                 /* 0x148 */
-       u64 int_stat_class2_RW;                                 /* 0x150 */
+       u64 int_stat_RW[3];                                     /* 0x140 */
        u8  pad_0x158_0x180[0x28];                              /* 0x158 */
        u64 int_route_RW;                                       /* 0x180 */