diff options
-rw-r--r-- | linux-core/drmP.h | 29 | ||||
-rw-r--r-- | linux/drmP.h | 29 | ||||
-rw-r--r-- | linux/r128_dma.c | 5 | ||||
-rw-r--r-- | linux/r128_drv.h | 39 | ||||
-rw-r--r-- | linux/vm.c | 2 |
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); \ @@ -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 */ } |