X-Git-Url: http://git.onelab.eu/?a=blobdiff_plain;f=drivers%2Fvideo%2Fmatrox%2Fmatroxfb_base.h;h=79a6873f7a5937d447375bf9b8aae619eddaea1c;hb=3ec04f3d2903fdf6d9849a8633af59b8628164a5;hp=72709cf22335a4778d31bb46853d7f252ebf66fc;hpb=8d40237c730b8be87c1b80a5d96b9c603fefa829;p=linux-2.6.git diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/matrox/matroxfb_base.h index 72709cf22..79a6873f7 100644 --- a/drivers/video/matrox/matroxfb_base.h +++ b/drivers/video/matrox/matroxfb_base.h @@ -93,6 +93,29 @@ #endif /* MATROXFB_DEBUG */ +#if !defined(__i386__) && !defined(__x86_64__) +#ifndef ioremap_nocache +#define ioremap_nocache(X,Y) ioremap(X,Y) +#endif +#endif + +#if defined(__alpha__) || defined(__mc68000__) || defined(__i386__) || defined(__x86_64__) +#define READx_WORKS +#define MEMCPYTOIO_WORKS +#else +/* ppc/ppc64 must use __raw_{read,write}[bwl] as we drive adapter + in big-endian mode for compatibility with XFree mga driver, and + so we do not want little-endian {read,write}[bwl] */ +#define READx_FAILS +#define MEMCPYTOIO_WRITEL +#endif + +#if defined(__mc68000__) +#define MAP_BUSTOVIRT +#else +#define MAP_IOREMAP +#endif + #ifdef DEBUG #define dprintk(X...) printk(X) #else @@ -132,13 +155,22 @@ #endif typedef struct { - void __iomem* vaddr; + u_int8_t __iomem* vaddr; } vaddr_t; +#ifdef READx_WORKS static inline unsigned int mga_readb(vaddr_t va, unsigned int offs) { return readb(va.vaddr + offs); } +static inline unsigned int mga_readw(vaddr_t va, unsigned int offs) { + return readw(va.vaddr + offs); +} + +static inline u_int32_t mga_readl(vaddr_t va, unsigned int offs) { + return readl(va.vaddr + offs); +} + static inline void mga_writeb(vaddr_t va, unsigned int offs, u_int8_t value) { writeb(value, va.vaddr + offs); } @@ -147,42 +179,62 @@ static inline void mga_writew(vaddr_t va, unsigned int offs, u_int16_t value) { writew(value, va.vaddr + offs); } +static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) { + writel(value, va.vaddr + offs); +} +#else +static inline unsigned int mga_readb(vaddr_t va, unsigned int offs) { + return __raw_readb(va.vaddr + offs); +} + +static inline unsigned int mga_readw(vaddr_t va, unsigned int offs) { + return __raw_readw(va.vaddr + offs); +} + static inline u_int32_t mga_readl(vaddr_t va, unsigned int offs) { - return readl(va.vaddr + offs); + return __raw_readl(va.vaddr + offs); } -static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) { - writel(value, va.vaddr + offs); +static inline void mga_writeb(vaddr_t va, unsigned int offs, u_int8_t value) { + __raw_writeb(value, va.vaddr + offs); } -static inline void mga_memcpy_toio(vaddr_t va, const void* src, int len) { -#if defined(__alpha__) || defined(__i386__) || defined(__x86_64__) - /* - * memcpy_toio works for us if: - * (1) Copies data as 32bit quantities, not byte after byte, - * (2) Performs LE ordered stores, and - * (3) It copes with unaligned source (destination is guaranteed to be page - * aligned and length is guaranteed to be multiple of 4). - */ - memcpy_toio(va.vaddr, src, len); -#else - u_int32_t __iomem* addr = va.vaddr; +static inline void mga_writew(vaddr_t va, unsigned int offs, u_int16_t value) { + __raw_writew(value, va.vaddr + offs); +} - if ((unsigned long)src & 3) { +static inline void mga_writel(vaddr_t va, unsigned int offs, u_int32_t value) { + __raw_writel(value, va.vaddr + offs); +} +#endif + +static inline void mga_memcpy_toio(vaddr_t va, unsigned int offs, const void* src, int len) { +#ifdef MEMCPYTOIO_WORKS + memcpy_toio(va.vaddr + offs, src, len); +#elif defined(MEMCPYTOIO_WRITEL) + if (offs & 3) { while (len >= 4) { - writel(get_unaligned((u32 *)src), addr); - addr++; + mga_writel(va, offs, get_unaligned((u32 *)src)); + offs += 4; len -= 4; src += 4; } } else { while (len >= 4) { - writel(*(u32 *)src, addr); - addr++; + mga_writel(va, offs, *(u32 *)src); + offs += 4; len -= 4; src += 4; } } + if (len) { + u_int32_t tmp; + + memcpy(&tmp, src, len); + mga_writel(va, offs, tmp); + } +#else +#error "Sorry, do not know how to write block of data to device" #endif } @@ -200,15 +252,25 @@ static inline void __iomem* vaddr_va(vaddr_t va) { #define MGA_IOREMAP_FB MGA_IOREMAP_NOCACHE #define MGA_IOREMAP_MMIO MGA_IOREMAP_NOCACHE static inline int mga_ioremap(unsigned long phys, unsigned long size, int flags, vaddr_t* virt) { +#ifdef MAP_IOREMAP if (flags & MGA_IOREMAP_NOCACHE) virt->vaddr = ioremap_nocache(phys, size); else virt->vaddr = ioremap(phys, size); +#else +#ifdef MAP_BUSTOVIRT + virt->vaddr = bus_to_virt(phys); +#else +#error "Your architecture does not have neither ioremap nor bus_to_virt... Giving up" +#endif +#endif return (virt->vaddr == 0); /* 0, !0... 0, error_code in future */ } static inline void mga_iounmap(vaddr_t va) { +#ifdef MAP_IOREMAP iounmap(va.vaddr); +#endif } struct my_timming { @@ -372,7 +434,6 @@ struct matrox_fb_info { struct list_head next_fb; int dead; - int initialized; unsigned int usecount; unsigned int userusecount; @@ -713,11 +774,11 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv); #define DAC_XGENIOCTRL 0x2A #define DAC_XGENIODATA 0x2B -#define M_C2CTL 0x3C10 - -#define MX_OPTION_BSWAP 0x00000000 +#define M_C2CTL 0x3E10 #ifdef __LITTLE_ENDIAN +#define MX_OPTION_BSWAP 0x00000000 + #define M_OPMODE_4BPP (M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT) #define M_OPMODE_8BPP (M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT) #define M_OPMODE_16BPP (M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT) @@ -725,23 +786,29 @@ void matroxfb_unregister_driver(struct matroxfb_driver* drv); #define M_OPMODE_32BPP (M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT) #else #ifdef __BIG_ENDIAN -#define M_OPMODE_4BPP (M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT) /* TODO */ -#define M_OPMODE_8BPP (M_OPMODE_DMA_LE | M_OPMODE_DIR_BE_8BPP | M_OPMODE_DMA_BLIT) -#define M_OPMODE_16BPP (M_OPMODE_DMA_LE | M_OPMODE_DIR_BE_16BPP | M_OPMODE_DMA_BLIT) -#define M_OPMODE_24BPP (M_OPMODE_DMA_LE | M_OPMODE_DIR_BE_8BPP | M_OPMODE_DMA_BLIT) /* TODO, ?32 */ -#define M_OPMODE_32BPP (M_OPMODE_DMA_LE | M_OPMODE_DIR_BE_32BPP | M_OPMODE_DMA_BLIT) +#define MX_OPTION_BSWAP 0x80000000 + +#define M_OPMODE_4BPP (M_OPMODE_DMA_LE | M_OPMODE_DIR_LE | M_OPMODE_DMA_BLIT) /* TODO */ +#define M_OPMODE_8BPP (M_OPMODE_DMA_BE_8BPP | M_OPMODE_DIR_BE_8BPP | M_OPMODE_DMA_BLIT) +#define M_OPMODE_16BPP (M_OPMODE_DMA_BE_16BPP | M_OPMODE_DIR_BE_16BPP | M_OPMODE_DMA_BLIT) +#define M_OPMODE_24BPP (M_OPMODE_DMA_BE_8BPP | M_OPMODE_DIR_BE_8BPP | M_OPMODE_DMA_BLIT) /* TODO, ?32 */ +#define M_OPMODE_32BPP (M_OPMODE_DMA_BE_32BPP | M_OPMODE_DIR_BE_32BPP | M_OPMODE_DMA_BLIT) #else #error "Byte ordering have to be defined. Cannot continue." #endif #endif -#define mga_inb(addr) mga_readb(ACCESS_FBINFO(mmio.vbase), (addr)) -#define mga_inl(addr) mga_readl(ACCESS_FBINFO(mmio.vbase), (addr)) -#define mga_outb(addr,val) mga_writeb(ACCESS_FBINFO(mmio.vbase), (addr), (val)) -#define mga_outw(addr,val) mga_writew(ACCESS_FBINFO(mmio.vbase), (addr), (val)) -#define mga_outl(addr,val) mga_writel(ACCESS_FBINFO(mmio.vbase), (addr), (val)) -#define mga_readr(port,idx) (mga_outb((port),(idx)), mga_inb((port)+1)) -#define mga_setr(addr,port,val) mga_outw(addr, ((val)<<8) | (port)) +#define mga_inb(addr) mga_readb(ACCESS_FBINFO(mmio.vbase), (addr)) +#define mga_inl(addr) mga_readl(ACCESS_FBINFO(mmio.vbase), (addr)) +#define mga_outb(addr,val) mga_writeb(ACCESS_FBINFO(mmio.vbase), (addr), (val)) +#define mga_outw(addr,val) mga_writew(ACCESS_FBINFO(mmio.vbase), (addr), (val)) +#define mga_outl(addr,val) mga_writel(ACCESS_FBINFO(mmio.vbase), (addr), (val)) +#define mga_readr(port,idx) (mga_outb((port),(idx)), mga_inb((port)+1)) +#ifdef __LITTLE_ENDIAN +#define mga_setr(addr,port,val) mga_outw(addr, ((val)<<8) | (port)) +#else +#define mga_setr(addr,port,val) do { mga_outb(addr, port); mga_outb((addr)+1, val); } while (0) +#endif #define mga_fifo(n) do {} while ((mga_inl(M_FIFOSTATUS) & 0xFF) < (n))