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

📄 tgafb.c

📁 S3C44B0X下的LCD (framebuffer)驱动资料与相关代码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* *  linux/drivers/video/tgafb.c -- DEC 21030 TGA frame buffer device * *	Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha *   *  $Id: tgafb.c,v 1.12.2.3 2000/04/04 06:44:56 mato Exp $ * *  This driver is partly based on the original TGA framebuffer device, which  *  was partly based on the original TGA console driver, which are * *	Copyright (C) 1997 Geert Uytterhoeven *	Copyright (C) 1995 Jay Estabrook * *  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. *//* KNOWN PROBLEMS/TO DO ===================================================== * * *	- How to set a single color register on 24-plane cards? * *	- Hardware cursor/other text acceleration methods * *	- Some redraws can stall kernel for several seconds *	  [This should now be solved by the fast memmove() patch in 2.3.6] * * KNOWN PROBLEMS/TO DO ==================================================== */#include <linux/module.h>#include <linux/sched.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/vmalloc.h>#include <linux/delay.h>#include <linux/interrupt.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/pci.h>#include <linux/selection.h>#include <linux/console.h>#include <asm/io.h>#include <video/fbcon.h>#include <video/fbcon-cfb8.h>#include <video/fbcon-cfb32.h>#include "tgafb.h"    /*     *  Global declarations     */static struct tgafb_info fb_info;static struct tgafb_par current_par;static int current_par_valid = 0;static struct display disp;static char default_fontname[40] __initdata = { 0 };static struct fb_var_screeninfo default_var;static int default_var_valid = 0;static int currcon = 0;static struct { u_char red, green, blue, pad; } palette[256];#ifdef FBCON_HAS_CFB32static u32 fbcon_cfb32_cmap[16];#endif    /*     *  Hardware presets     */static unsigned int fb_offset_presets[4] = {	TGA_8PLANE_FB_OFFSET,	TGA_24PLANE_FB_OFFSET,	0xffffffff,	TGA_24PLUSZ_FB_OFFSET};static unsigned int deep_presets[4] = {  0x00014000,  0x0001440d,  0xffffffff,  0x0001441d};static unsigned int rasterop_presets[4] = {  0x00000003,  0x00000303,  0xffffffff,  0x00000303};static unsigned int mode_presets[4] = {  0x00002000,  0x00002300,  0xffffffff,  0x00002300};static unsigned int base_addr_presets[4] = {  0x00000000,  0x00000001,  0xffffffff,  0x00000001};    /*     *  Predefined video modes     *  This is a subset of the standard VESA modes, recalculated from XFree86.     *     *  XXX Should we store these in terms of the encoded par structs? Even better,     *      fbcon should provide a general mechanism for doing something like this.     */static struct {    const char *name;    struct fb_var_screeninfo var;} tgafb_predefined[] __initdata = {    { "640x480-60", {	640, 480, 640, 480, 0, 0, 0, 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,	0,	FB_VMODE_NONINTERLACED    }},    { "800x600-56", {	800, 600, 800, 600, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 27777, 128, 24, 22, 1, 72, 2,	0,	FB_VMODE_NONINTERLACED    }},    { "640x480-72", {	640, 480, 640, 480, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 31746, 144, 40, 30, 8, 40, 3,	0,	FB_VMODE_NONINTERLACED    }},    { "800x600-60", {	800, 600, 800, 600, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 25000, 88, 40, 23, 1, 128, 4,	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,	FB_VMODE_NONINTERLACED    }},    { "800x600-72", {	800, 600, 800, 600, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 20000, 64, 56, 23, 37, 120, 6,	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,	FB_VMODE_NONINTERLACED    }},    { "1024x768-60", {	1024, 768, 1024, 768, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 15384, 168, 8, 29, 3, 144, 6,	0,	FB_VMODE_NONINTERLACED    }},    { "1152x864-60", {	1152, 864, 1152, 864, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 11123, 208, 64, 16, 4, 256, 8,	0,	FB_VMODE_NONINTERLACED    }},    { "1024x768-70", {	1024, 768, 1024, 768, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 13333, 144, 24, 29, 3, 136, 6,	0,	FB_VMODE_NONINTERLACED    }},    { "1024x768-76", {	1024, 768, 1024, 768, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 11764, 208, 8, 36, 16, 120, 3,	0,	FB_VMODE_NONINTERLACED    }},    { "1152x864-70", {	1152, 864, 1152, 864, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 10869, 106, 56, 20, 1, 160, 10,	0,	FB_VMODE_NONINTERLACED    }},    { "1280x1024-61", {	1280, 1024, 1280, 1024, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 9090, 200, 48, 26, 1, 184, 3,	0,	FB_VMODE_NONINTERLACED    }},    { "1024x768-85", {	1024, 768, 1024, 768, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 10111, 192, 32, 34, 14, 160, 6,	0,	FB_VMODE_NONINTERLACED    }},    { "1280x1024-70", {	1280, 1024, 1280, 1024, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 7905, 224, 32, 28, 8, 160, 8,	0,	FB_VMODE_NONINTERLACED    }},    { "1152x864-84", {	1152, 864, 1152, 864, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 7407, 184, 312, 32, 0, 128, 12,	0,	FB_VMODE_NONINTERLACED    }},    { "1280x1024-76", {	1280, 1024, 1280, 1024, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 7407, 248, 32, 34, 3, 104, 3,	0,	FB_VMODE_NONINTERLACED    }},    { "1280x1024-85", {	1280, 1024, 1280, 1024, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 6349, 224, 64, 44, 1, 160, 3,	0,	FB_VMODE_NONINTERLACED    }},    /* These are modes used by the two fixed-frequency monitors I have at home.      * You may or may not find these useful.     */    { "WYSE1", {			/* 1280x1024 @ 72 Hz, 130 Mhz clock */	1280, 1024, 1280, 1024, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 7692, 192, 32, 47, 0, 192, 5,	FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT,	FB_VMODE_NONINTERLACED    }},    { "IBM3", {				/* 1280x1024 @ 70 Hz, 120 Mhz clock */	1280, 1024, 1280, 1024, 0, 0, 0, 0,	{0, 8, 0}, {0, 8, 0}, {0, 8, 0}, {0, 0, 0},	0, 0, -1, -1, FB_ACCELF_TEXT, 8333, 192, 32, 47, 0, 192, 5,	0,	FB_VMODE_NONINTERLACED    }}};#define NUM_TOTAL_MODES    ARRAY_SIZE(tgafb_predefined)    /*     *  Interface used by the world     */static void tgafb_detect(void);static int tgafb_encode_fix(struct fb_fix_screeninfo *fix, const void *fb_par,		        struct fb_info_gen *info);static int tgafb_decode_var(const struct fb_var_screeninfo *var, void *fb_par,		        struct fb_info_gen *info);static int tgafb_encode_var(struct fb_var_screeninfo *var, const void *fb_par,		        struct fb_info_gen *info);static void tgafb_get_par(void *fb_par, struct fb_info_gen *info);static void tgafb_set_par(const void *fb_par, struct fb_info_gen *info);static int tgafb_getcolreg(u_int regno, u_int *red, u_int *green, u_int *blue, 		u_int *transp, struct fb_info *info);static int tgafb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 		u_int transp, struct fb_info *info);static int tgafb_blank(int blank, struct fb_info_gen *info);static void tgafb_set_disp(const void *fb_par, struct display *disp, 		struct fb_info_gen *info);#ifndef MODULEint tgafb_setup(char*);#endifstatic void tgafb_set_pll(int f);#if 1static int tgafb_set_cmap(struct fb_cmap *cmap, int kspc, int con,			  struct fb_info *info);static void tgafb_update_palette(void);#endif    /*     *  Chipset specific functions     */static void tgafb_detect(void){    return;}static int tgafb_encode_fix(struct fb_fix_screeninfo *fix, const void *fb_par,	struct fb_info_gen *info){    struct tgafb_par *par = (struct tgafb_par *)fb_par;    strcpy(fix->id, fb_info.gen.info.modename);    fix->type = FB_TYPE_PACKED_PIXELS;    fix->type_aux = 0;    if (fb_info.tga_type == TGA_TYPE_8PLANE) {	fix->visual = FB_VISUAL_PSEUDOCOLOR;    } else {	fix->visual = FB_VISUAL_TRUECOLOR;    }    fix->line_length = par->xres * (par->bits_per_pixel >> 3);    fix->smem_start = fb_info.tga_fb_base;    fix->smem_len = fix->line_length * par->yres;    fix->mmio_start = fb_info.tga_regs_base;    fix->mmio_len = 0x1000;		/* Is this sufficient? */    fix->xpanstep = fix->ypanstep = fix->ywrapstep = 0;    fix->accel = FB_ACCEL_DEC_TGA;    return 0;}static int tgafb_decode_var(const struct fb_var_screeninfo *var, void *fb_par,	struct fb_info_gen *info){    struct tgafb_par *par = (struct tgafb_par *)fb_par;    /* round up some */    if (fb_info.tga_type == TGA_TYPE_8PLANE) {	if (var->bits_per_pixel > 8) {	    return -EINVAL;	}	par->bits_per_pixel = 8;    } else {	if (var->bits_per_pixel > 32) {	    return -EINVAL;	}	par->bits_per_pixel = 32;    }    /* check the values for sanity */    if (var->xres_virtual != var->xres ||	var->yres_virtual != var->yres ||	var->nonstd || (1000000000/var->pixclock) > TGA_PLL_MAX_FREQ ||	(var->vmode & FB_VMODE_MASK) != FB_VMODE_NONINTERLACED#if 0	/* fbmon not done.  uncomment for 2.5.x -brad */	|| !fbmon_valid_timings(var->pixclock, var->htotal, var->vtotal, info))#else	)#endif	return -EINVAL;    /* encode video timings */    par->htimings = ((var->xres/4) & TGA_HORIZ_ACT_LSB) | 	(((var->xres/4) & 0x600 << 19) & TGA_HORIZ_ACT_MSB);    par->vtimings = (var->yres & TGA_VERT_ACTIVE);    par->htimings |= ((var->right_margin/4) << 9) & TGA_HORIZ_FP;    par->vtimings |= (var->lower_margin << 11) & TGA_VERT_FP;    par->htimings |= ((var->hsync_len/4) << 14) & TGA_HORIZ_SYNC;    par->vtimings |= (var->vsync_len << 16) & TGA_VERT_SYNC;    par->htimings |= ((var->left_margin/4) << 21) & TGA_HORIZ_BP;    par->vtimings |= (var->upper_margin << 22) & TGA_VERT_BP;    if (var->sync & FB_SYNC_HOR_HIGH_ACT)	par->htimings |= TGA_HORIZ_POLARITY;    if (var->sync & FB_SYNC_VERT_HIGH_ACT)	par->vtimings |= TGA_VERT_POLARITY;    if (var->sync & FB_SYNC_ON_GREEN) {	par->sync_on_green = 1;    } else {	par->sync_on_green = 0;    }    /* store other useful values in par */    par->xres = var->xres;     par->yres = var->yres;    par->pll_freq = 1000000000/var->pixclock;    par->bits_per_pixel = var->bits_per_pixel;    return 0;}static int tgafb_encode_var(struct fb_var_screeninfo *var, const void *fb_par,	struct fb_info_gen *info){    struct tgafb_par *par = (struct tgafb_par *)fb_par;    /* decode video timings */    var->xres = ((par->htimings & TGA_HORIZ_ACT_LSB) | ((par->htimings & TGA_HORIZ_ACT_MSB) >> 19)) * 4;    var->yres = (par->vtimings & TGA_VERT_ACTIVE);    var->right_margin = ((par->htimings & TGA_HORIZ_FP) >> 9) * 4;    var->lower_margin = ((par->vtimings & TGA_VERT_FP) >> 11);    var->hsync_len = ((par->htimings & TGA_HORIZ_SYNC) >> 14) * 4;    var->vsync_len = ((par->vtimings & TGA_VERT_SYNC) >> 16);    var->left_margin = ((par->htimings & TGA_HORIZ_BP) >> 21) * 4;    var->upper_margin = ((par->vtimings & TGA_VERT_BP) >> 22);    if (par->htimings & TGA_HORIZ_POLARITY)     	var->sync |= FB_SYNC_HOR_HIGH_ACT;    if (par->vtimings & TGA_VERT_POLARITY)    	var->sync |= FB_SYNC_VERT_HIGH_ACT;    if (par->sync_on_green == 1)	var->sync |= FB_SYNC_ON_GREEN;    var->xres_virtual = var->xres;    var->yres_virtual = var->yres;    var->xoffset = var->yoffset = 0;    /* depth-related */    if (fb_info.tga_type == TGA_TYPE_8PLANE) {	var->red.offset = 0;	var->green.offset = 0;	var->blue.offset = 0;    } else {	var->red.offset = 16;	var->green.offset = 8;	var->blue.offset = 0;    }    var->bits_per_pixel = par->bits_per_pixel;    var->grayscale = 0;    var->red.length = var->green.length = var->blue.length = 8;    var->red.msb_right = var->green.msb_right = var->blue.msb_right = 0;    var->transp.offset = var->transp.length = var->transp.msb_right = 0;    /* others */    var->xoffset = var->yoffset = 0;    var->pixclock = 1000000000/par->pll_freq;    var->nonstd = 0;    var->activate = 0;    var->height = var->width = -1;    var->accel_flags = 0;    return 0;}static void tgafb_get_par(void *fb_par, struct fb_info_gen *info){    struct tgafb_par *par = (struct tgafb_par *)fb_par;    if (current_par_valid)	*par = current_par;    else {	if (fb_info.tga_type == TGA_TYPE_8PLANE)	    default_var.bits_per_pixel = 8;	else	    default_var.bits_per_pixel = 32;	tgafb_decode_var(&default_var, par, info);    }}static void tgafb_set_par(const void *fb_par, struct fb_info_gen *info){    int i, j;    struct tgafb_par *par = (struct tgafb_par *)fb_par;#if 0    /* XXX this will break console switching with X11, maybe I need to test KD_GRAPHICS? */    /* if current_par is valid, check to see if we need to change anything */    if (current_par_valid) {	if (!memcmp(par, &current_par, sizeof current_par)) {	    return;	}    }#endif    current_par = *par;    current_par_valid = 1;    /* first, disable video */    TGA_WRITE_REG(TGA_VALID_VIDEO | TGA_VALID_BLANK, TGA_VALID_REG);        /* write the DEEP register */    while (TGA_READ_REG(TGA_CMD_STAT_REG) & 1) /* wait for not busy */      continue;    mb();    TGA_WRITE_REG(deep_presets[fb_info.tga_type], TGA_DEEP_REG);    while (TGA_READ_REG(TGA_CMD_STAT_REG) & 1) /* wait for not busy */	continue;    mb();    /* write some more registers */    TGA_WRITE_REG(rasterop_presets[fb_info.tga_type], TGA_RASTEROP_REG);    TGA_WRITE_REG(mode_presets[fb_info.tga_type], TGA_MODE_REG);    TGA_WRITE_REG(base_addr_presets[fb_info.tga_type], TGA_BASE_ADDR_REG);    /* calculate & write the PLL */    tgafb_set_pll(par->pll_freq);    /* write some more registers */    TGA_WRITE_REG(0xffffffff, TGA_PLANEMASK_REG);    TGA_WRITE_REG(0xffffffff, TGA_PIXELMASK_REG);

⌨️ 快捷键说明

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