summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--linux-core/drmP.h29
-rw-r--r--linux/drmP.h29
-rw-r--r--linux/r128_dma.c5
-rw-r--r--linux/r128_drv.h39
-rw-r--r--linux/vm.c2
5 files changed, 104 insertions, 0 deletions
diff --git a/linux-core/drmP.h b/linux-core/drmP.h
index 4f85d07c..128d6dd1 100644
--- a/linux-core/drmP.h
+++ b/linux-core/drmP.h
@@ -49,6 +49,7 @@
#include <asm/io.h>
#include <asm/mman.h>
#include <asm/uaccess.h>
+#include <asm/pgtable.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
@@ -148,6 +149,7 @@ typedef struct wait_queue *wait_queue_head_t;
#ifndef __HAVE_ARCH_CMPXCHG
/* Include this here so that driver can be
used with older kernels. */
+#if defined(__i386__)
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
@@ -174,6 +176,33 @@ 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;
+}
+#endif
#define cmpxchg(ptr,o,n) \
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
diff --git a/linux/drmP.h b/linux/drmP.h
index 4f85d07c..128d6dd1 100644
--- a/linux/drmP.h
+++ b/linux/drmP.h
@@ -49,6 +49,7 @@
#include <asm/io.h>
#include <asm/mman.h>
#include <asm/uaccess.h>
+#include <asm/pgtable.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
@@ -148,6 +149,7 @@ typedef struct wait_queue *wait_queue_head_t;
#ifndef __HAVE_ARCH_CMPXCHG
/* Include this here so that driver can be
used with older kernels. */
+#if defined(__i386__)
static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old,
unsigned long new, int size)
{
@@ -174,6 +176,33 @@ 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;
+}
+#endif
#define cmpxchg(ptr,o,n) \
((__typeof__(*(ptr)))__cmpxchg((ptr),(unsigned long)(o), \
diff --git a/linux/r128_dma.c b/linux/r128_dma.c
index 16f79c1f..e1dc6f5e 100644
--- a/linux/r128_dma.c
+++ b/linux/r128_dma.c
@@ -72,6 +72,7 @@ static void r128_flush_write_combine(void)
{
int xchangeDummy;
+#ifdef __i386__
__asm__ volatile("push %%eax ;"
"xchg %%eax, %0 ;"
"pop %%eax" : : "m" (xchangeDummy));
@@ -85,6 +86,10 @@ static void r128_flush_write_combine(void)
"pop %%ecx ;"
"pop %%ebx ;"
"pop %%eax" : /* no outputs */ : /* no inputs */ );
+#else
+ /* The lack write combining makes life easy :) */
+ mb();
+#endif
}
static void r128_status(drm_device_t *dev)
diff --git a/linux/r128_drv.h b/linux/r128_drv.h
index 5b15dddf..91ad9f53 100644
--- a/linux/r128_drv.h
+++ b/linux/r128_drv.h
@@ -197,6 +197,43 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_MAX_USEC_TIMEOUT 100000 /* 100 ms */
+#ifdef __powerpc__
+
+static __inline__ void
+WriteMmio32Le(void *base, const unsigned long offset,
+ const unsigned long val)
+{
+ __asm__ __volatile__(
+ "stwbrx %1,%2,%3\n\t"
+ : "=m" (*(volatile unsigned char *)(base+offset))
+ : "r" (val), "b" (base), "r" (offset));
+}
+
+static __inline__ unsigned int
+ReadMmio32Le(void *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 unsigned char *)(base+offset)));
+ return(val);
+}
+
+#define R128_BASE(reg) ((u32)(dev_priv->mmio->handle))
+#define R128_ADDR(reg) (R128_BASE(reg) + reg)
+
+#define R128_READ(reg) ReadMmio32Le(R128_BASE(reg),reg)
+#define R128_WRITE(reg,val) WriteMmio32Le(R128_BASE(reg),reg,val)
+
+#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)
+
+#else /* ! __powerpc__ */
+
#define R128_BASE(reg) ((u32)(dev_priv->mmio->handle))
#define R128_ADDR(reg) (R128_BASE(reg) + reg)
@@ -208,6 +245,8 @@ extern int r128_context_switch_complete(drm_device_t *dev, int new);
#define R128_READ8(reg) R128_DEREF8(reg)
#define R128_WRITE8(reg,val) do { R128_DEREF8(reg) = val; } while (0)
+#endif /* __powerpc__ */
+
#define R128_WRITE_PLL(addr,val) \
do { \
R128_WRITE8(R128_CLOCK_CNTL_INDEX, ((addr) & 0x1f) | R128_PLL_WR_EN); \
diff --git a/linux/vm.c b/linux/vm.c
index d295529b..907c44cf 100644
--- a/linux/vm.c
+++ b/linux/vm.c
@@ -323,6 +323,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;
#endif
vma->vm_flags |= VM_IO; /* not in core dump */
}