summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drmP.h30
-rw-r--r--linux/drmP.h30
-rw-r--r--linux/r128_drv.h37
-rw-r--r--linux/vm.c2
4 files changed, 93 insertions, 6 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 6be90c51..2f3458f2 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -53,7 +53,7 @@
#include <linux/sched.h>
#include <linux/smp_lock.h> /* For (un)lock_kernel */
#include <linux/mm.h>
-#ifdef __alpha__
+#if defined(__alpha__) || defined(__powerpc__)
#include <asm/pgtable.h> /* For pte_wrprotect */
#endif
#include <asm/io.h>
@@ -247,11 +247,37 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
}
return old;
}
+#elif defined(__powerpc__)
+extern void __cmpxchg_called_with_bad_pointer(void);
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long prev;
+
+ switch (size) {
+ case 4:
+ __asm__ __volatile__(
+ "sync;"
+ "0: lwarx %0,0,%1 ;"
+ " cmpl 0,%0,%3;"
+ " bne 1f;"
+ " stwcx. %2,0,%1;"
+ " bne- 0b;"
+ "1: "
+ "sync;"
+ : "=&r"(prev)
+ : "r"(ptr), "r"(new), "r"(old)
+ : "cr0", "memory");
+ return prev;
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
#define cmpxchg(ptr,o,n) \
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
(unsigned long)(n),sizeof(*(ptr))))
-#endif /* i386 & alpha */
+#endif /* i386, powerpc & alpha */
#endif
/* Macros to make printk easier */
diff --git a/linux/drmP.h b/linux/drmP.h
index 6be90c51..2f3458f2 100644
--- a/linux/drmP.h
+++ b/linux/drmP.h
@@ -53,7 +53,7 @@
#include <linux/sched.h>
#include <linux/smp_lock.h> /* For (un)lock_kernel */
#include <linux/mm.h>
-#ifdef __alpha__
+#if defined(__alpha__) || defined(__powerpc__)
#include <asm/pgtable.h> /* For pte_wrprotect */
#endif
#include <asm/io.h>
@@ -247,11 +247,37 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
}
return old;
}
+#elif defined(__powerpc__)
+extern void __cmpxchg_called_with_bad_pointer(void);
+static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
+ unsigned long new, int size)
+{
+ unsigned long prev;
+
+ switch (size) {
+ case 4:
+ __asm__ __volatile__(
+ "sync;"
+ "0: lwarx %0,0,%1 ;"
+ " cmpl 0,%0,%3;"
+ " bne 1f;"
+ " stwcx. %2,0,%1;"
+ " bne- 0b;"
+ "1: "
+ "sync;"
+ : "=&r"(prev)
+ : "r"(ptr), "r"(new), "r"(old)
+ : "cr0", "memory");
+ return prev;
+ }
+ __cmpxchg_called_with_bad_pointer();
+ return old;
+}
#define cmpxchg(ptr,o,n) \
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
(unsigned long)(n),sizeof(*(ptr))))
-#endif /* i386 & alpha */
+#endif /* i386, powerpc & alpha */
#endif
/* Macros to make printk easier */
diff --git a/linux/r128_drv.h b/linux/r128_drv.h
index 63b98c72..2249a01e 100644
--- a/linux/r128_drv.h
+++ b/linux/r128_drv.h
@@ -26,6 +26,7 @@
*
* Authors: Rickard E. (Rik) Faith <faith@valinux.com>
* Kevin E. Martin <martin@valinux.com>
+ * Michel Dänzer <daenzerm@student.ethz.ch>
*
*/
@@ -197,13 +198,45 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */
-#define R128_BASE(reg) ((u32)(dev_priv->mmio->handle))
-#define R128_ADDR(reg) (R128_BASE(reg) + reg)
+#ifdef __powerpc__
+
+static __inline__ void
+WriteMmio32Le(int *base, const unsigned long offset,
+ const unsigned long val)
+{
+ __asm__ __volatile__(
+ "stwbrx %1,%2,%3\n\t"
+ : "=m" (*(volatile int *)(base+offset))
+ : "r" (val), "b" (base), "r" (offset));
+}
+
+static __inline__ unsigned int
+ReadMmio32Le(int *base, const unsigned long offset)
+{
+ register unsigned int val;
+ __asm__ __volatile__(
+ "lwbrx %0,%1,%2\n\t"
+ "eieio"
+ : "=r" (val)
+ : "b" (base), "r" (offset),
+ "m" (*(volatile int *)(base+offset)));
+ return(val);
+}
+
+#define R128_READ(reg) ReadMmio32Le((int *)R128_BASE(reg),reg)
+#define R128_WRITE(reg,val) WriteMmio32Le((int *)R128_BASE(reg),reg,val)
+
+#else /* ! __powerpc__; FIXME: other big endian machines need their own code here */
#define R128_DEREF(reg) *(__volatile__ int *)R128_ADDR(reg)
#define R128_READ(reg) R128_DEREF(reg)
#define R128_WRITE(reg,val) do { R128_DEREF(reg) = val; } while (0)
+#endif /* __powerpc__ */
+
+#define R128_BASE(reg) ((unsigned long)(dev_priv->mmio->handle))
+#define R128_ADDR(reg) (R128_BASE(reg) + reg)
+
#define R128_DEREF8(reg) *(__volatile__ char *)R128_ADDR(reg)
#define R128_READ8(reg) R128_DEREF8(reg)
#define R128_WRITE8(reg,val) do { R128_DEREF8(reg) = val; } while (0)
diff --git a/linux/vm.c b/linux/vm.c
index 964921b4..aa689451 100644
--- a/linux/vm.c
+++ b/linux/vm.c
@@ -321,6 +321,8 @@ int drm_mmap(struct file *filp, struct vm_area_struct *vma)
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
}
+#elif defined(__powerpc__)
+ pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE|_PAGE_GUARDED;
#elif defined(__ia64__)
if (map->type != _DRM_AGP)
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);