|
From: Steve L. <slo...@us...> - 2001-09-12 22:23:34
|
Update of /cvsroot/linux-mips/linux/drivers/video
In directory usw-pr-cvs1:/tmp/cvs-serv30384/drivers/video
Modified Files:
epson1356fb.c epson1356fb.h
Log Message:
- added a boot flag "mmunalign" to enable 32-bit unaligned VA fix
in mmap().
- optimized mymemset_io() and renamed to fbfill().
- clear fb memory when video mode changes (e1356fb_set_par()).
- more elaborate comments.
Index: epson1356fb.c
===================================================================
RCS file: /cvsroot/linux-mips/linux/drivers/video/epson1356fb.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -C2 -d -r1.4 -r1.5
*** epson1356fb.c 2001/08/30 21:41:05 1.4
--- epson1356fb.c 2001/09/12 22:23:31 1.5
***************
*** 71,77 ****
#include <linux/e1356fb.h>
! #ifdef CONFIG_MIPS_PB1000
#include <asm/au1000.h>
- #define USE_MMAP 1
#endif
--- 71,76 ----
#include <linux/e1356fb.h>
! #ifdef CONFIG_MIPS_AU1000
#include <asm/au1000.h>
#endif
***************
*** 112,120 ****
int con,
struct fb_info* info);
- #ifdef USE_MMAP
static int e1356fb_mmap(struct fb_info *info,
struct file *file,
struct vm_area_struct *vma);
- #endif
/*
--- 111,117 ----
***************
*** 198,204 ****
fb_pan_display: e1356fb_pan_display,
fb_ioctl: e1356fb_ioctl,
- #ifdef USE_MMAP
fb_mmap: e1356fb_mmap,
- #endif
};
--- 195,199 ----
***************
*** 257,275 ****
* ------------------------------------------------------------------------- */
! #ifdef CONFIG_MIPS_PB1000
! // MIPS memset_io does 32-bit word writes. Frame buffer
! // accesses on the Alchemy Pb1000 board can only be 8
! // or 16 bits wide.
static inline void
! mymemset_io(void* addr, u8 val, int size)
{
! //u16 valw = (u16)val | ((u16)val << 8);
! //size >>= 1;
! while (size--)
! writeb(val, (u8*)addr++);
}
- #else
- #define mymemset_io memset_io
- #endif
static inline int
--- 252,272 ----
* ------------------------------------------------------------------------- */
! /*
! * The SED1356 has only a 16-bit wide data bus, so some embedded
! * implementations with 32-bit CPU's (Alchemy Pb1000) may not
! * correctly emulate a 32-bit write to the framebuffer by splitting
! * the write into two seperate 16-bit writes. So it is safest to
! * only do byte or half-word writes to the fb. This routine assumes
! * fbaddr is atleast aligned on a half-word boundary.
! */
static inline void
! fbfill(u16* fbaddr, u8 val, int size)
{
! u16 valw = (u16)val | ((u16)val << 8);
! for ( ; size >= 2; size -= 2)
! writew(valw, fbaddr++);
! if (size)
! writeb(val, (u8*)fbaddr);
}
static inline int
***************
*** 1247,1251 ****
u16 height, addr_offset;
int disp_type = info->fix.disp_type;
!
#ifdef E1356FB_VERBOSE_DEBUG
dump_par(par);
--- 1244,1252 ----
u16 height, addr_offset;
int disp_type = info->fix.disp_type;
! int hsync = (1000 * par->ipclk.pixclk) / (par->width + par->horiz_ndp);
!
! DPRINTK("%dx%d-%dbpp @ %d Hz, %d kHz hsync\n",
! par->width, par->height, par->bpp,
! hsync / (par->height + par->vert_ndp), (((2*hsync)/1000)+1)/2);
#ifdef E1356FB_VERBOSE_DEBUG
dump_par(par);
***************
*** 1343,1353 ****
writeb(display_mode, &dispmode->disp_mode);
! #ifdef CONFIG_MIPS_PB1000
! if (info->fix.system == SYS_PB1000 && info->mmaped)
writeb(1, &dispmode->start_addr0);
else
- #else
writeb(0, &dispmode->start_addr0);
- #endif
writeb(0, &dispmode->start_addr1);
writeb(0, &dispmode->start_addr2);
--- 1344,1351 ----
writeb(display_mode, &dispmode->disp_mode);
! if (info->fix.mmunalign && info->mmaped)
writeb(1, &dispmode->start_addr0);
else
writeb(0, &dispmode->start_addr0);
writeb(0, &dispmode->start_addr1);
writeb(0, &dispmode->start_addr2);
***************
*** 1362,1365 ****
--- 1360,1365 ----
#endif
+ /* clear out framebuffer memory */
+ fbfill(fb_info.membase_virt, 0, fb_info.fb_size);
// finally, enable display!
writeb(main_display_mode, &info->reg.misc->disp_mode);
***************
*** 1677,1681 ****
int activate = var->activate;
int j,k;
- int hsync;
//DPRINTK("\n");
--- 1677,1680 ----
***************
*** 1689,1696 ****
return err;
- hsync = (1000 * par.ipclk.pixclk) / (par.width + par.horiz_ndp);
- printk("e1356fb: mode selected: %dx%d-%d @ %d Hz, %d kHz hsync\n",
- par.width, par.height, par.bpp,
- hsync / (par.height + par.vert_ndp), (((2*hsync)/1000)+1)/2);
if (info->fix.tv_filt & TV_FILT_FLICKER)
printk("e1356fb: TV flicker filter enabled\n");
--- 1688,1691 ----
***************
*** 1884,1888 ****
- #ifdef USE_MMAP
static int
e1356fb_mmap(struct fb_info *fb,
--- 1879,1882 ----
***************
*** 1946,1968 ****
pgprot_val(vma->vm_page_prot) |= (_PAGE_DIRTY | _PAGE_VALID);
- #ifdef CONFIG_MIPS_PB1000
/*
! * The Pb1000 does not handle 32-bit load/stores to the
! * SED1356 display memory, only 8 or 16-bit accesses work.
! * So do this: intentionally return a non-32-bit-aligned VA.
! * This way the MIPS unaligned exception handler will emulate
! * the load/store instructions by splitting up the 32-bit
! * load/store into two 16-bit load/stores (thanks Ralf!).
! * Address error emulation is currently enabled by default,
! * but this feature may be disabled in the future, when
* alignment problems in user-level programs get fixed. When
* that happens, this solution won't work anymore, unless the
* process that mmap's the fb also calls sysmips(MIPS_FIXADE, 1),
! * which turns address-error emulation back on.
*/
! if (info->fix.system == SYS_PB1000)
vma->vm_start += 2;
! #endif
!
if (io_remap_page_range(vma->vm_start, off,
vma->vm_end - vma->vm_start,
--- 1940,1970 ----
pgprot_val(vma->vm_page_prot) |= (_PAGE_DIRTY | _PAGE_VALID);
/*
! * The SED1356 has only a 16-bit wide data bus, and some
! * embedded platforms, such as the Pb1000, do not automatically
! * split 32-bit word accesses to the framebuffer into
! * seperate half-word accesses. Hence the upper half-word
! * never gets to the framebuffer. The following solution is
! * to intentionally return a non-32-bit-aligned VA. As long
! * as the user app assumes (and doesn't check) that the returned
! * VA is 32-bit aligned, all (assumed aligned) 32-bit accesses
! * will actually be unaligned and will get trapped by the MIPS
! * unaligned exception handler. This handler will emulate the
! * load/store instructions by splitting up the load/store
! * into two 16-bit load/stores. (This emulation is currently
! * enabled by default, but may be disabled in the future, when
* alignment problems in user-level programs get fixed. When
* that happens, this solution won't work anymore, unless the
* process that mmap's the fb also calls sysmips(MIPS_FIXADE, 1),
! * which turns address-error emulation back on).
! *
! * Furthermore, this solution only seems to work for TinyX
! * (Xfbdev). Others, like Qt/E, do snoop the returned VA
! * and compensate, or do originally unaligned 32-bit accesses
! * which then become aligned, hence breaking this solution.
*/
! if (info->fix.mmunalign)
vma->vm_start += 2;
!
if (io_remap_page_range(vma->vm_start, off,
vma->vm_end - vma->vm_start,
***************
*** 1973,1977 ****
return 0;
}
- #endif
--- 1975,1978 ----
***************
*** 2109,2117 ****
*/
! #ifdef CONFIG_MIPS_PB1000
! if (epfix->system == SYS_PB1000) {
! extern unsigned int get_au1000_lcd_clock(void);
epfix->busclk = get_au1000_lcd_clock();
- }
#endif
--- 2110,2116 ----
*/
! #ifdef CONFIG_MIPS_AU1000
! if (epfix->system == SYS_PB1000)
epfix->busclk = get_au1000_lcd_clock();
#endif
***************
*** 2264,2271 ****
fb_info.fb_info.changevar = NULL;
fb_info.fb_info.node = -1;
! #ifdef USE_MMAP
! if (epfix->system != SYS_PB1000)
! e1356fb_ops.fb_mmap = NULL;
! #endif
fb_info.fb_info.fbops = &e1356fb_ops;
fb_info.fb_info.disp = &fb_info.disp;
--- 2263,2267 ----
fb_info.fb_info.changevar = NULL;
fb_info.fb_info.node = -1;
!
fb_info.fb_info.fbops = &e1356fb_ops;
fb_info.fb_info.disp = &fb_info.disp;
***************
*** 2391,2397 ****
writeb(0, ®->misc->cpu2mem_watchdog); // disable watchdog timer
- /* clear framebuffer memory */
- mymemset_io(fb_info.membase_virt, 0, fb_info.fb_size);
-
#ifdef E1356FB_VERBOSE_DEBUG
dump_fb(fb_info.membase_virt + 0x100000, 512);
--- 2387,2390 ----
***************
*** 2408,2413 ****
fb_info.fb_info.modename);
- /* FIXME: module cannot be unloaded */
- /* verify e1356fb_exit before removing this */
MOD_INC_USE_COUNT;
--- 2401,2404 ----
***************
*** 2479,2482 ****
--- 2470,2476 ----
} else if (!strncmp(this_opt, "nohwcursor", 10)) {
boot_fix.nohwcursor = 1;
+ } else if (!strncmp(this_opt, "mmunalign:", 10)) {
+ boot_fix.mmunalign = simple_strtoul(this_opt+10,
+ NULL, 0);
#ifdef CONFIG_MTRR
} else if (!strncmp(this_opt, "nomtrr", 6)) {
***************
*** 2795,2799 ****
e1356fb_createcursor(struct display *p)
{
! u8* memcursor;
int y, w, h, u;
--- 2789,2793 ----
e1356fb_createcursor(struct display *p)
{
! void* memcursor;
int y, w, h, u;
***************
*** 2802,2815 ****
h = fb_info.cursor.h;
w = fb_info.cursor.w;
u = fb_info.cursor.u;
! memcursor = (u8*)fb_info.membase_virt + fb_info.fb_size;
// write cursor to display memory
for (y=0; y<64; y++) {
if (y >= h || y < u) {
! mymemset_io(memcursor, 0xaa, 16); // b/g
} else {
! mymemset_io(memcursor, 0xff, w/4); // inverted b/g
! mymemset_io(memcursor + w/4, 0xaa, (64 - w)/4); // b/g
}
memcursor += 16;
--- 2796,2810 ----
h = fb_info.cursor.h;
w = fb_info.cursor.w;
+ DPRINTK("w=%d\n", w);
u = fb_info.cursor.u;
! memcursor = fb_info.membase_virt + fb_info.fb_size;
// write cursor to display memory
for (y=0; y<64; y++) {
if (y >= h || y < u) {
! fbfill((u16*)memcursor, 0xaa, 16); // b/g
} else {
! fbfill((u16*)memcursor, 0xff, w/4); // inverted b/g
! fbfill((u16*)memcursor + w/4, 0xaa, (64 - w)/4); // b/g
}
memcursor += 16;
Index: epson1356fb.h
===================================================================
RCS file: /cvsroot/linux-mips/linux/drivers/video/epson1356fb.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -C2 -d -r1.3 -r1.4
*** epson1356fb.h 2001/08/30 21:41:05 1.3
--- epson1356fb.h 2001/09/12 22:23:31 1.4
***************
*** 331,334 ****
--- 331,335 ----
#endif
int nohwcursor;
+ int mmunalign; // force unaligned returned VA in mmap()
char fontname[40];
***************
*** 482,485 ****
--- 483,487 ----
#endif
0,
+ 0,
{0},
"800x600@60"
***************
*** 514,517 ****
--- 516,520 ----
#endif
0,
+ 0,
{0},
"800x600@60"
***************
*** 543,546 ****
--- 546,550 ----
0,
#endif
+ 0,
0,
{0},
|