Skip to content

Commit

Permalink
fbdev: Move framebuffer I/O helpers into <asm/fb.h>
Browse files Browse the repository at this point in the history
Implement framebuffer I/O helpers, such as fb_read*() and fb_write*(),
in the architecture's <asm/fb.h> header file or the generic one.

The common case has been the use of regular I/O functions, such as
__raw_readb() or memset_io(). A few architectures used plain system-
memory reads and writes. Sparc used helpers for its SBus.

The architectures that used special cases provide the same code in
their __raw_*() I/O helpers. So the patch replaces this code with the
__raw_*() functions and moves it to <asm-generic/fb.h> for all
architectures.

v5:
	* include <linux/io.h> in <asm-generic/fb>; fix s390 build
v4:
	* ia64, loongarch, sparc64: add fb_mem*() to arch headers
	  to keep current semantics (Arnd)
v3:
	* implement all architectures with generic helpers
	* support reordering and native byte order (Geert, Arnd)

Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Tested-by: Sui Jingfeng <suijingfeng@loongson.cn>
Reviewed-by: Arnd Bergmann <arnd@arndb.de>
  • Loading branch information
Thomas Zimmermann authored and intel-lab-lkp committed May 8, 2023
1 parent 7f82cc9 commit c64dc7f
Show file tree
Hide file tree
Showing 5 changed files with 163 additions and 53 deletions.
20 changes: 20 additions & 0 deletions arch/ia64/include/asm/fb.h
Expand Up @@ -2,7 +2,9 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_

#include <linux/compiler.h>
#include <linux/efi.h>
#include <linux/string.h>

#include <asm/page.h>

Expand All @@ -18,6 +20,24 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
}
#define fb_pgprotect fb_pgprotect

static inline void fb_memcpy_fromfb(void *to, const volatile void __iomem *from, size_t n)
{
memcpy(to, (void __force *)from, n);
}
#define fb_memcpy_fromfb fb_memcpy_fromfb

static inline void fb_memcpy_tofb(volatile void __iomem *to, const void *from, size_t n)
{
memcpy((void __force *)to, from, n);
}
#define fb_memcpy_tofb fb_memcpy_tofb

static inline void fb_memset(volatile void __iomem *addr, int c, size_t n)
{
memset((void __force *)addr, c, n);
}
#define fb_memset fb_memset

#include <asm-generic/fb.h>

#endif /* _ASM_FB_H_ */
21 changes: 21 additions & 0 deletions arch/loongarch/include/asm/fb.h
Expand Up @@ -5,6 +5,27 @@
#ifndef _ASM_FB_H_
#define _ASM_FB_H_

#include <linux/compiler.h>
#include <linux/string.h>

static inline void fb_memcpy_fromfb(void *to, const volatile void __iomem *from, size_t n)
{
memcpy(to, (void __force *)from, n);
}
#define fb_memcpy_fromfb fb_memcpy_fromfb

static inline void fb_memcpy_tofb(volatile void __iomem *to, const void *from, size_t n)
{
memcpy((void __force *)to, from, n);
}
#define fb_memcpy_tofb fb_memcpy_tofb

static inline void fb_memset(volatile void __iomem *addr, int c, size_t n)
{
memset((void __force *)addr, c, n);
}
#define fb_memset fb_memset

#include <asm-generic/fb.h>

#endif /* _ASM_FB_H_ */
20 changes: 20 additions & 0 deletions arch/sparc/include/asm/fb.h
Expand Up @@ -2,6 +2,8 @@
#ifndef _SPARC_FB_H_
#define _SPARC_FB_H_

#include <linux/io.h>

struct fb_info;
struct file;
struct vm_area_struct;
Expand All @@ -16,6 +18,24 @@ static inline void fb_pgprotect(struct file *file, struct vm_area_struct *vma,
int fb_is_primary_device(struct fb_info *info);
#define fb_is_primary_device fb_is_primary_device

static inline void fb_memcpy_fromfb(void *to, const volatile void __iomem *from, size_t n)
{
sbus_memcpy_fromio(to, from, n);
}
#define fb_memcpy_fromfb fb_memcpy_fromfb

static inline void fb_memcpy_tofb(volatile void __iomem *to, const void *from, size_t n)
{
sbus_memcpy_toio(to, from, n);
}
#define fb_memcpy_tofb fb_memcpy_tofb

static inline void fb_memset(volatile void __iomem *addr, int c, size_t n)
{
sbus_memset_io(addr, c, n);
}
#define fb_memset fb_memset

#include <asm-generic/fb.h>

#endif /* _SPARC_FB_H_ */
102 changes: 102 additions & 0 deletions include/asm-generic/fb.h
Expand Up @@ -7,6 +7,7 @@
* Only include this header file from your architecture's <asm/fb.h>.
*/

#include <linux/io.h>
#include <linux/mm_types.h>
#include <linux/pgtable.h>

Expand All @@ -30,4 +31,105 @@ static inline int fb_is_primary_device(struct fb_info *info)
}
#endif

/*
* I/O helpers for the framebuffer. Prefer these functions over their
* regular counterparts. The regular I/O functions provide in-order
* access and swap bytes to/from little-endian ordering. Neither is
* required for framebuffers. Instead, the helpers read and write
* raw framebuffer data. Independent operations can be reordered for
* improved performance.
*/

#ifndef fb_readb
static inline u8 fb_readb(const volatile void __iomem *addr)
{
return __raw_readb(addr);
}
#define fb_readb fb_readb
#endif

#ifndef fb_readw
static inline u16 fb_readw(const volatile void __iomem *addr)
{
return __raw_readw(addr);
}
#define fb_readw fb_readw
#endif

#ifndef fb_readl
static inline u32 fb_readl(const volatile void __iomem *addr)
{
return __raw_readl(addr);
}
#define fb_readl fb_readl
#endif

#ifndef fb_readq
#if defined(__raw_readq)
static inline u64 fb_readq(const volatile void __iomem *addr)
{
return __raw_readq(addr);
}
#define fb_readq fb_readq
#endif
#endif

#ifndef fb_writeb
static inline void fb_writeb(u8 b, volatile void __iomem *addr)
{
__raw_writeb(b, addr);
}
#define fb_writeb fb_writeb
#endif

#ifndef fb_writew
static inline void fb_writew(u16 b, volatile void __iomem *addr)
{
__raw_writew(b, addr);
}
#define fb_writew fb_writew
#endif

#ifndef fb_writel
static inline void fb_writel(u32 b, volatile void __iomem *addr)
{
__raw_writel(b, addr);
}
#define fb_writel fb_writel
#endif

#ifndef fb_writeq
#if defined(__raw_writeq)
static inline void fb_writeq(u64 b, volatile void __iomem *addr)
{
__raw_writeq(b, addr);
}
#define fb_writeq fb_writeq
#endif
#endif

#ifndef fb_memcpy_fromfb
static inline void fb_memcpy_fromfb(void *to, const volatile void __iomem *from, size_t n)
{
memcpy_fromio(to, from, n);
}
#define fb_memcpy_fromfb fb_memcpy_fromfb
#endif

#ifndef fb_memcpy_tofb
static inline void fb_memcpy_tofb(volatile void __iomem *to, const void *from, size_t n)
{
memcpy_toio(to, from, n);
}
#define fb_memcpy_tofb fb_memcpy_tofb
#endif

#ifndef fb_memset
static inline void fb_memset(volatile void __iomem *addr, int c, size_t n)
{
memset_io(addr, c, n);
}
#define fb_memset fb_memset
#endif

#endif /* __ASM_GENERIC_FB_H_ */
53 changes: 0 additions & 53 deletions include/linux/fb.h
Expand Up @@ -17,7 +17,6 @@
#include <linux/slab.h>

#include <asm/fb.h>
#include <asm/io.h>

struct vm_area_struct;
struct fb_info;
Expand Down Expand Up @@ -513,58 +512,6 @@ struct fb_info {
*/
#define STUPID_ACCELF_TEXT_SHIT

// This will go away
#if defined(__sparc__)

/* We map all of our framebuffers such that big-endian accesses
* are what we want, so the following is sufficient.
*/

// This will go away
#define fb_readb sbus_readb
#define fb_readw sbus_readw
#define fb_readl sbus_readl
#define fb_readq sbus_readq
#define fb_writeb sbus_writeb
#define fb_writew sbus_writew
#define fb_writel sbus_writel
#define fb_writeq sbus_writeq
#define fb_memset sbus_memset_io
#define fb_memcpy_fromfb sbus_memcpy_fromio
#define fb_memcpy_tofb sbus_memcpy_toio

#elif defined(__i386__) || defined(__alpha__) || defined(__x86_64__) || \
defined(__hppa__) || defined(__sh__) || defined(__powerpc__) || \
defined(__arm__) || defined(__aarch64__) || defined(__mips__)

#define fb_readb __raw_readb
#define fb_readw __raw_readw
#define fb_readl __raw_readl
#define fb_readq __raw_readq
#define fb_writeb __raw_writeb
#define fb_writew __raw_writew
#define fb_writel __raw_writel
#define fb_writeq __raw_writeq
#define fb_memset memset_io
#define fb_memcpy_fromfb memcpy_fromio
#define fb_memcpy_tofb memcpy_toio

#else

#define fb_readb(addr) (*(volatile u8 *) (addr))
#define fb_readw(addr) (*(volatile u16 *) (addr))
#define fb_readl(addr) (*(volatile u32 *) (addr))
#define fb_readq(addr) (*(volatile u64 *) (addr))
#define fb_writeb(b,addr) (*(volatile u8 *) (addr) = (b))
#define fb_writew(b,addr) (*(volatile u16 *) (addr) = (b))
#define fb_writel(b,addr) (*(volatile u32 *) (addr) = (b))
#define fb_writeq(b,addr) (*(volatile u64 *) (addr) = (b))
#define fb_memset memset
#define fb_memcpy_fromfb memcpy
#define fb_memcpy_tofb memcpy

#endif

#define FB_LEFT_POS(p, bpp) (fb_be_math(p) ? (32 - (bpp)) : 0)
#define FB_SHIFT_HIGH(p, val, bits) (fb_be_math(p) ? (val) >> (bits) : \
(val) << (bits))
Expand Down

0 comments on commit c64dc7f

Please sign in to comment.