⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 cyberfb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 5 页
字号:
/** linux/drivers/video/cyberfb.c -- CyberVision64 frame buffer device* $Id: cyberfb.c,v 1.6 1998/09/11 04:54:58 abair Exp $**    Copyright (C) 1998 Alan Bair** This file is based on two CyberVision64 frame buffer device drivers** The second CyberVision64 frame buffer device (cvision.c cvision_core.c):**   Copyright (c) 1997 Antonio Santos** Released as a patch to 2.1.35, but never included in the source tree.* This is based on work from the NetBSD CyberVision64 frame buffer driver * and support files (grf_cv.c, grf_cvreg.h, ite_cv.c):* Permission to use the source of this driver was obtained from the* author Michael Teske by Alan Bair.**   Copyright (c) 1995 Michael Teske** The first CyberVision64 frame buffer device (cyberfb.c):**    Copyright (C) 1996 Martin Apel*                       Geert Uytterhoeven** Which is based on the Amiga frame buffer device (amifb.c):**    Copyright (C) 1995 Geert Uytterhoeven*** History:*   - 22 Dec 95: Original version by Martin Apel*   - 05 Jan 96: Geert: integration into the current source tree*   - 01 Aug 98: Alan: Merge in code from cvision.c and cvision_core.c* $Log: cyberfb.c,v $* Revision 1.6  1998/09/11 04:54:58  abair* Update for 2.1.120 change in include file location.* Clean up for public release.** Revision 1.5  1998/09/03 04:27:13  abair* Move cv64_load_video_mode to cyber_set_video so a new video mode is install* with each change of the 'var' data.** Revision 1.4  1998/09/01 00:31:17  abair* Put in a set of default 8,16,24 bpp modes and map cyber8,16 to them.* Update operations with 'par' to handle a more complete set of parameter* values for encode/decode process.** Revision 1.3  1998/08/31 21:31:33  abair* Swap 800x490 for 640x480 video mode and more cleanup.* Abandon idea to resurrect "custom" mode setting via kernel opts,* instead work on making use of fbset program to do this.** Revision 1.2  1998/08/31 06:17:08  abair* Make updates for changes in cyberfb.c released in 2.1.119* and do some cleanup of the code.** Revision 1.1  1998/08/29 18:38:31  abair* Initial revision** Revision 1.3  1998/08/17 06:21:53  abair* Remove more redundant code after merging in cvision_core.c* Set blanking by colormap to pale red to detect this vs trying to* use video blanking. More formating to Linux code style.** Revision 1.2  1998/08/15 17:51:37  abair* Added cvision_core.c code from 2.1.35 patches.* Changed to compile correctly and switch to using initialization* code. Added debugging and dropping of duplicate code.**** This file is subject to the terms and conditions of the GNU General Public* License.  See the file COPYING in the main directory of this archive* for more details.*/#include <linux/module.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/tty.h>#include <linux/slab.h>#include <linux/delay.h>#include <linux/zorro.h>#include <linux/fb.h>#include <linux/init.h>#include <asm/uaccess.h>#include <asm/system.h>#include <asm/irq.h>#include <asm/pgtable.h>#include <asm/amigahw.h>#include <asm/io.h>#include "cyberfb.h"#include <video/fbcon.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb16.h>/*#define CYBERFBDEBUG*/#ifdef CYBERFBDEBUG#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)static void cv64_dump(void);#else#define DPRINTK(fmt, args...)#endif#define wb_64(regs,reg,dat) (*(((volatile unsigned char *)regs) + reg) = dat)#define rb_64(regs, reg) (*(((volatile unsigned char *)regs) + reg))#define ww_64(regs,reg,dat) (*((volatile unsigned short *)(regs + reg) = dat)struct cyberfb_par {	struct fb_var_screeninfo var;	__u32 type;	__u32 type_aux;	__u32 visual;	__u32 line_length;};static struct cyberfb_par current_par;static int current_par_valid = 0;static int currcon = 0;static struct display disp;static struct fb_info fb_info;/* *    Frame Buffer Name */static char cyberfb_name[16] = "Cybervision";/* *    CyberVision Graphics Board */static unsigned char Cyber_colour_table [256][3];static unsigned long CyberSize;static volatile unsigned char *CyberBase;static volatile unsigned char *CyberMem;static volatile unsigned char *CyberRegs;static unsigned long CyberMem_phys;static unsigned long CyberRegs_phys;/* *    Predefined Video Modes */static struct {    const char *name;    struct fb_var_screeninfo var;} cyberfb_predefined[] __initdata = {	{ "640x480-8", {		/* Default 8 BPP mode (cyber8) */		640, 480, 640, 480, 0, 0, 8, 0,		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},		0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,		FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, 		FB_VMODE_NONINTERLACED	}}, 	{ "640x480-16", {		/* Default 16 BPP mode (cyber16) */		640, 480, 640, 480, 0, 0, 16, 0,		{11, 5, 0}, {5, 6, 0}, {0, 5, 0}, {0, 0, 0},		0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,		FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, 		FB_VMODE_NONINTERLACED	}}, 	{ "640x480-24", {		/* Default 24 BPP mode */		640, 480, 640, 480, 0, 0, 24, 0,		{16, 8, 0}, {8, 8, 0}, {0, 8, 0}, {0, 0, 0},		0, 0, -1, -1, FB_ACCELF_TEXT, 39722, 40, 24, 32, 11, 96, 2,		FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, 		FB_VMODE_NONINTERLACED	}}, 	{ "800x490-8", {		/* Cybervision 8 bpp */		/* NO Acceleration */		800, 490, 800, 490, 0, 0, 8, 0,		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},		0, 0, -1, -1, FB_ACCEL_NONE, 33333, 80, 24, 23, 1, 56, 8,		FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,		FB_VMODE_NONINTERLACED	}},/* I can't test these with my monitor, but I suspect they will * be OK, since Antonio Santos indicated he had tested them in * his system. */	{ "800x600-8", {		/* Cybervision 8 bpp */		800, 600, 800, 600, 0, 0, 8, 0,		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},		0, 0, -1, -1, FB_ACCELF_TEXT, 27778, 64, 24, 22, 1, 72, 2,		FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,		FB_VMODE_NONINTERLACED	}},	{ "1024x768-8", {		/* Cybervision 8 bpp */		1024, 768, 1024, 768, 0, 0, 8, 0,		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},		0, 0, -1, -1, FB_ACCELF_TEXT, 16667, 224, 72, 60, 12, 168, 4,		FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,		FB_VMODE_NONINTERLACED	}},	{ "1152x886-8", {		/* Cybervision 8 bpp */		1152, 886, 1152, 886, 0, 0, 8, 0,		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},		0, 0, -1, -1, FB_ACCELF_TEXT, 15873, 184, 40, 24, 1, 56, 16,		FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,		FB_VMODE_NONINTERLACED	}},	{ "1280x1024-8", {	/* Cybervision 8 bpp */		1280, 1024, 1280, 1024, 0, 0, 8, 0,		{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},		0, 0, -1, -1, FB_ACCELF_TEXT, 16667, 256, 48, 50, 12, 72, 4,		FB_SYNC_COMP_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,		FB_VMODE_INTERLACED	}}};#define NUM_TOTAL_MODES    ARRAY_SIZE(cyberfb_predefined)static int Cyberfb_inverse = 0;/* *    Some default modes */#define CYBER8_DEFMODE     (0)#define CYBER16_DEFMODE    (1)static struct fb_var_screeninfo cyberfb_default;static int cyberfb_usermode __initdata = 0;/* *    Interface used by the world */int cyberfb_setup(char *options);static int cyberfb_get_fix(struct fb_fix_screeninfo *fix, int con,			   struct fb_info *info);static int cyberfb_get_var(struct fb_var_screeninfo *var, int con,			   struct fb_info *info);static int cyberfb_set_var(struct fb_var_screeninfo *var, int con,			   struct fb_info *info);static int cyberfb_get_cmap(struct fb_cmap *cmap, int kspc, int con,			    struct fb_info *info);static int cyberfb_set_cmap(struct fb_cmap *cmap, int kspc, int con,			    struct fb_info *info);/* *    Interface to the low level console driver */int cyberfb_init(void);static int Cyberfb_switch(int con, struct fb_info *info);static int Cyberfb_updatevar(int con, struct fb_info *info);static void Cyberfb_blank(int blank, struct fb_info *info);/* *    Text console acceleration */#ifdef FBCON_HAS_CFB8static struct display_switch fbcon_cyber8;#endif/* *    Accelerated Functions used by the low level console driver */static void Cyber_WaitQueue(u_short fifo);static void Cyber_WaitBlit(void);static void Cyber_BitBLT(u_short curx, u_short cury, u_short destx,			 u_short desty, u_short width, u_short height,			 u_short mode);static void Cyber_RectFill(u_short x, u_short y, u_short width, u_short height,			   u_short mode, u_short color);#if 0static void Cyber_MoveCursor(u_short x, u_short y);#endif/* *   Hardware Specific Routines */static int Cyber_init(void);static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,			    struct cyberfb_par *par);static int Cyber_decode_var(struct fb_var_screeninfo *var,			    struct cyberfb_par *par);static int Cyber_encode_var(struct fb_var_screeninfo *var,			    struct cyberfb_par *par);static int Cyber_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue,			   u_int *transp, struct fb_info *info);static int Cyber_setcolreg(u_int regno, u_int red, u_int green, u_int blue,			   u_int transp, struct fb_info *info);/* *    Internal routines */static void cyberfb_get_par(struct cyberfb_par *par);static void cyberfb_set_par(struct cyberfb_par *par);static int do_fb_set_var(struct fb_var_screeninfo *var, int isactive);static void do_install_cmap(int con, struct fb_info *info);static void cyberfb_set_disp(int con, struct fb_info *info);static int get_video_mode(const char *name);/* For cvision_core.c */static unsigned short cv64_compute_clock(unsigned long);static int cv_has_4mb (volatile unsigned char *);static void cv64_board_init (void);static void cv64_load_video_mode (struct fb_var_screeninfo *);/* -------------------- Hardware specific routines ------------------------- *//* *    Initialization * *    Set the default video mode for this chipset. If a video mode was *    specified on the command line, it will override the default mode. */static int Cyber_init(void){	volatile unsigned char *regs = CyberRegs;	volatile unsigned long *CursorBase;	int i;	DPRINTK("ENTER\n");/* Init local cmap as greyscale levels */	for (i = 0; i < 256; i++) {		Cyber_colour_table [i][0] = i;		Cyber_colour_table [i][1] = i;		Cyber_colour_table [i][2] = i;	}/* Initialize the board and determine fbmem size */	cv64_board_init(); #ifdef CYBERFBDEBUG	DPRINTK("Register state after initing board\n");	cv64_dump();#endif/* Clear framebuffer memory */	DPRINTK("Clear framebuffer memory\n");	memset ((char *)CyberMem, 0, CyberSize);/* Disable hardware cursor */	DPRINTK("Disable HW cursor\n");	wb_64(regs, S3_CRTC_ADR, S3_REG_LOCK2);	wb_64(regs, S3_CRTC_DATA, 0xa0);	wb_64(regs, S3_CRTC_ADR, S3_HGC_MODE);	wb_64(regs, S3_CRTC_DATA, 0x00);	wb_64(regs, S3_CRTC_ADR, S3_HWGC_DX);	wb_64(regs, S3_CRTC_DATA, 0x00);	wb_64(regs, S3_CRTC_ADR, S3_HWGC_DY);	wb_64(regs, S3_CRTC_DATA, 0x00);/* Initialize hardware cursor */	DPRINTK("Init HW cursor\n");	CursorBase = (u_long *)((char *)(CyberMem) + CyberSize - 0x400);	for (i=0; i < 8; i++)	{		*(CursorBase  +(i*4)) = 0xffffff00;		*(CursorBase+1+(i*4)) = 0xffff0000;		*(CursorBase+2+(i*4)) = 0xffff0000;		*(CursorBase+3+(i*4)) = 0xffff0000;	}	for (i=8; i < 64; i++)	{		*(CursorBase  +(i*4)) = 0xffff0000;		*(CursorBase+1+(i*4)) = 0xffff0000;		*(CursorBase+2+(i*4)) = 0xffff0000;		*(CursorBase+3+(i*4)) = 0xffff0000;	}	Cyber_setcolreg (255, 56<<8, 100<<8, 160<<8, 0, NULL /* unused */);	Cyber_setcolreg (254, 0, 0, 0, 0, NULL /* unused */);	DPRINTK("EXIT\n");	return 0;}/* *    This function should fill in the `fix' structure based on the *    values in the `par' structure. */static int Cyber_encode_fix(struct fb_fix_screeninfo *fix,			    struct cyberfb_par *par){	DPRINTK("ENTER\n");	memset(fix, 0, sizeof(struct fb_fix_screeninfo));	strcpy(fix->id, cyberfb_name);	fix->smem_start = CyberMem_phys;	fix->smem_len = CyberSize;	fix->mmio_start = CyberRegs_phys;	fix->mmio_len = 0x10000;	fix->type = FB_TYPE_PACKED_PIXELS;	fix->type_aux = 0;	if (par->var.bits_per_pixel == 15 || par->var.bits_per_pixel == 16 ||	    par->var.bits_per_pixel == 24 || par->var.bits_per_pixel == 32) {		fix->visual = FB_VISUAL_DIRECTCOLOR;	} else {		fix->visual = FB_VISUAL_PSEUDOCOLOR;	}	fix->xpanstep = 0;	fix->ypanstep = 0;	fix->ywrapstep = 0;	fix->line_length = 0;	fix->accel = FB_ACCEL_S3_TRIO64;	DPRINTK("EXIT\n");	return(0);}/**    Fill the `par' structure based on the values in `var'.*    TODO: Verify and adjust values, return -EINVAL if bad.*/static int Cyber_decode_var(struct fb_var_screeninfo *var,			    struct cyberfb_par *par){	DPRINTK("ENTER\n");	par->var.xres = var->xres;	par->var.yres = var->yres;	par->var.xres_virtual = var->xres_virtual;	par->var.yres_virtual = var->yres_virtual;	par->var.xoffset = var->xoffset;	par->var.yoffset = var->yoffset;	par->var.bits_per_pixel = var->bits_per_pixel;	par->var.grayscale = var->grayscale;	par->var.red = var->red;	par->var.green = var->green;	par->var.blue = var->blue;	par->var.transp = var->transp;	par->var.nonstd = var->nonstd;	par->var.activate = var->activate;	par->var.height = var->height;	par->var.width = var->width;	if (var->accel_flags & FB_ACCELF_TEXT) {		par->var.accel_flags = FB_ACCELF_TEXT;	} else {		par->var.accel_flags = 0;	}	par->var.pixclock = var->pixclock;	par->var.left_margin = var->left_margin;	par->var.right_margin = var->right_margin;	par->var.upper_margin = var->upper_margin;	par->var.lower_margin = var->lower_margin;	par->var.hsync_len = var->hsync_len;	par->var.vsync_len = var->vsync_len;	par->var.sync = var->sync;	par->var.vmode = var->vmode;	DPRINTK("EXIT\n");	return(0);}/**    Fill the `var' structure based on the values in `par' and maybe*    other values read out of the hardware.*/

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -