diff options
-rw-r--r-- | linux-core/drmP.h | 30 | ||||
-rw-r--r-- | linux/drmP.h | 30 | ||||
-rw-r--r-- | linux/r128_drv.h | 37 | ||||
-rw-r--r-- | linux/vm.c | 2 |
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) @@ -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); |