au1200fb.c
来自「Linux环境下视频显示卡设备的驱动程序源代码」· C语言 代码 · 共 1,922 行 · 第 1/4 页
C
1,922 行
/* * BRIEF MODULE DESCRIPTION * Au1200 LCD Driver. * * Copyright 2004-2005 AMD * Author: AMD * * Based on: * linux/drivers/video/skeletonfb.c -- Skeleton for a frame buffer device * Created 28 Dec 1997 by Geert Uytterhoeven * * This program is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the * Free Software Foundation; either version 2 of the License, or (at your * option) any later version. * * THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN * NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. * * You should have received a copy of the GNU General Public License along * with this program; if not, write to the Free Software Foundation, Inc., * 675 Mass Ave, Cambridge, MA 02139, USA. */#include <linux/module.h>#include <linux/platform_device.h>#include <linux/kernel.h>#include <linux/errno.h>#include <linux/string.h>#include <linux/mm.h>#include <linux/fb.h>#include <linux/init.h>#include <linux/interrupt.h>#include <linux/ctype.h>#include <linux/dma-mapping.h>#include <asm/mach-au1x00/au1000.h>#include "au1200fb.h"#ifdef CONFIG_PM#include <asm/mach-au1x00/au1xxx_pm.h>#endif#ifndef CONFIG_FB_AU1200_DEVS#define CONFIG_FB_AU1200_DEVS 4#endif#define DRIVER_NAME "au1200fb"#define DRIVER_DESC "LCD controller driver for AU1200 processors"#define DEBUG 1#define print_err(f, arg...) printk(KERN_ERR DRIVER_NAME ": " f "\n", ## arg)#define print_warn(f, arg...) printk(KERN_WARNING DRIVER_NAME ": " f "\n", ## arg)#define print_info(f, arg...) printk(KERN_INFO DRIVER_NAME ": " f "\n", ## arg)#if DEBUG#define print_dbg(f, arg...) printk(KERN_DEBUG __FILE__ ": " f "\n", ## arg)#else#define print_dbg(f, arg...) do {} while (0)#endif#define AU1200_LCD_FB_IOCTL 0x46FF#define AU1200_LCD_SET_SCREEN 1#define AU1200_LCD_GET_SCREEN 2#define AU1200_LCD_SET_WINDOW 3#define AU1200_LCD_GET_WINDOW 4#define AU1200_LCD_SET_PANEL 5#define AU1200_LCD_GET_PANEL 6#define SCREEN_SIZE (1<< 1)#define SCREEN_BACKCOLOR (1<< 2)#define SCREEN_BRIGHTNESS (1<< 3)#define SCREEN_COLORKEY (1<< 4)#define SCREEN_MASK (1<< 5)struct au1200_lcd_global_regs_t { unsigned int flags; unsigned int xsize; unsigned int ysize; unsigned int backcolor; unsigned int brightness; unsigned int colorkey; unsigned int mask; unsigned int panel_choice; char panel_desc[80];};#define WIN_POSITION (1<< 0)#define WIN_ALPHA_COLOR (1<< 1)#define WIN_ALPHA_MODE (1<< 2)#define WIN_PRIORITY (1<< 3)#define WIN_CHANNEL (1<< 4)#define WIN_BUFFER_FORMAT (1<< 5)#define WIN_COLOR_ORDER (1<< 6)#define WIN_PIXEL_ORDER (1<< 7)#define WIN_SIZE (1<< 8)#define WIN_COLORKEY_MODE (1<< 9)#define WIN_DOUBLE_BUFFER_MODE (1<< 10)#define WIN_RAM_ARRAY_MODE (1<< 11)#define WIN_BUFFER_SCALE (1<< 12)#define WIN_ENABLE (1<< 13)struct au1200_lcd_window_regs_t { unsigned int flags; unsigned int xpos; unsigned int ypos; unsigned int alpha_color; unsigned int alpha_mode; unsigned int priority; unsigned int channel; unsigned int buffer_format; unsigned int color_order; unsigned int pixel_order; unsigned int xsize; unsigned int ysize; unsigned int colorkey_mode; unsigned int double_buffer_mode; unsigned int ram_array_mode; unsigned int xscale; unsigned int yscale; unsigned int enable;};struct au1200_lcd_iodata_t { unsigned int subcmd; struct au1200_lcd_global_regs_t global; struct au1200_lcd_window_regs_t window;};#if defined(__BIG_ENDIAN)#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_11#else#define LCD_CONTROL_DEFAULT_PO LCD_CONTROL_PO_00#endif#define LCD_CONTROL_DEFAULT_SBPPF LCD_CONTROL_SBPPF_565/* Private, per-framebuffer management information (independent of the panel itself) */struct au1200fb_device { struct fb_info fb_info; /* FB driver info record */ int plane; unsigned char* fb_mem; /* FrameBuffer memory map */ unsigned int fb_len; dma_addr_t fb_phys;};static struct au1200fb_device _au1200fb_devices[CONFIG_FB_AU1200_DEVS];/********************************************************************//* LCD controller restrictions */#define AU1200_LCD_MAX_XRES 1280#define AU1200_LCD_MAX_YRES 1024#define AU1200_LCD_MAX_BPP 32#define AU1200_LCD_MAX_CLK 96000000 /* fixme: this needs to go away ? */#define AU1200_LCD_NBR_PALETTE_ENTRIES 256/* Default number of visible screen buffer to allocate */#define AU1200FB_NBR_VIDEO_BUFFERS 1/********************************************************************/static struct au1200_lcd *lcd = (struct au1200_lcd *) AU1200_LCD_ADDR;static int window_index = 2; /* default is zero */static int panel_index = 2; /* default is zero */static struct window_settings *win;static struct panel_settings *panel;static int noblanking = 1;static int nohwcursor = 0;struct window_settings { unsigned char name[64]; uint32 mode_backcolor; uint32 mode_colorkey; uint32 mode_colorkeymsk; struct { int xres; int yres; int xpos; int ypos; uint32 mode_winctrl1; /* winctrl1[FRM,CCO,PO,PIPE] */ uint32 mode_winenable; } w[4];};#if defined(__BIG_ENDIAN)#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_00#else#define LCD_WINCTRL1_PO_16BPP LCD_WINCTRL1_PO_01#endifextern int board_au1200fb_panel_init (void);extern int board_au1200fb_panel_shutdown (void);#ifdef CONFIG_PMint au1200fb_pm_callback(au1xxx_power_dev_t *dev, au1xxx_request_t request, void *data);au1xxx_power_dev_t *LCD_pm_dev;#endif/* * Default window configurations */static struct window_settings windows[] = { { /* Index 0 */ "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", /* mode_backcolor */ 0x006600ff, /* mode_colorkey,msk*/ 0, 0, { { /* xres, yres, xpos, ypos */ 0, 0, 0, 0, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | LCD_WINCTRL1_PO_16BPP, /* mode_winenable*/ LCD_WINENABLE_WEN0, }, { /* xres, yres, xpos, ypos */ 100, 100, 100, 100, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | LCD_WINCTRL1_PO_16BPP | LCD_WINCTRL1_PIPE, /* mode_winenable*/ LCD_WINENABLE_WEN1, }, { /* xres, yres, xpos, ypos */ 0, 0, 0, 0, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | LCD_WINCTRL1_PO_16BPP, /* mode_winenable*/ 0, }, { /* xres, yres, xpos, ypos */ 0, 0, 0, 0, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | LCD_WINCTRL1_PO_16BPP | LCD_WINCTRL1_PIPE, /* mode_winenable*/ 0, }, }, }, { /* Index 1 */ "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", /* mode_backcolor */ 0x006600ff, /* mode_colorkey,msk*/ 0, 0, { { /* xres, yres, xpos, ypos */ 320, 240, 5, 5, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_24BPP | LCD_WINCTRL1_PO_00, /* mode_winenable*/ LCD_WINENABLE_WEN0, }, { /* xres, yres, xpos, ypos */ 0, 0, 0, 0, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | LCD_WINCTRL1_PO_16BPP, /* mode_winenable*/ 0, }, { /* xres, yres, xpos, ypos */ 100, 100, 0, 0, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | LCD_WINCTRL1_PO_16BPP | LCD_WINCTRL1_PIPE, /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/, }, { /* xres, yres, xpos, ypos */ 200, 25, 0, 0, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | LCD_WINCTRL1_PO_16BPP | LCD_WINCTRL1_PIPE, /* mode_winenable*/ 0, }, }, }, { /* Index 2 */ "0-FS gfx, 1-video, 2-ovly gfx, 3-ovly gfx", /* mode_backcolor */ 0x006600ff, /* mode_colorkey,msk*/ 0, 0, { { /* xres, yres, xpos, ypos */ 0, 0, 0, 0, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | LCD_WINCTRL1_PO_16BPP, /* mode_winenable*/ LCD_WINENABLE_WEN0, }, { /* xres, yres, xpos, ypos */ 0, 0, 0, 0, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | LCD_WINCTRL1_PO_16BPP, /* mode_winenable*/ 0, }, { /* xres, yres, xpos, ypos */ 0, 0, 0, 0, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_32BPP | LCD_WINCTRL1_PO_00|LCD_WINCTRL1_PIPE, /* mode_winenable*/ 0/*LCD_WINENABLE_WEN2*/, }, { /* xres, yres, xpos, ypos */ 0, 0, 0, 0, /* mode_winctrl1 */ LCD_WINCTRL1_FRM_16BPP565 | LCD_WINCTRL1_PO_16BPP | LCD_WINCTRL1_PIPE, /* mode_winenable*/ 0, }, }, }, /* Need VGA 640 @ 24bpp, @ 32bpp */ /* Need VGA 800 @ 24bpp, @ 32bpp */ /* Need VGA 1024 @ 24bpp, @ 32bpp */};/* * Controller configurations for various panels. */struct panel_settings{ const char name[25]; /* Full name <vendor>_<model> */ struct fb_monspecs monspecs; /* FB monitor specs */ /* panel timings */ uint32 mode_screen; uint32 mode_horztiming; uint32 mode_verttiming; uint32 mode_clkcontrol; uint32 mode_pwmdiv; uint32 mode_pwmhi; uint32 mode_outmask; uint32 mode_fifoctrl; uint32 mode_toyclksrc; uint32 mode_backlight; uint32 mode_auxpll; int (*device_init)(void); int (*device_shutdown)(void);#define Xres min_xres#define Yres min_yres u32 min_xres; /* Minimum horizontal resolution */ u32 max_xres; /* Maximum horizontal resolution */ u32 min_yres; /* Minimum vertical resolution */ u32 max_yres; /* Maximum vertical resolution */};/********************************************************************//* fixme: Maybe a modedb for the CRT ? otherwise panels should be as-is *//* List of panels known to work with the AU1200 LCD controller. * To add a new panel, enter the same specifications as the * Generic_TFT one, and MAKE SURE that it doesn't conflicts * with the controller restrictions. Restrictions are: * * STN color panels: max_bpp <= 12 * STN mono panels: max_bpp <= 4 * TFT panels: max_bpp <= 16 * max_xres <= 800 * max_yres <= 600 */static struct panel_settings known_lcd_panels[] ={ [0] = { /* QVGA 320x240 H:33.3kHz V:110Hz */ .name = "QVGA_320x240", .monspecs = { .modedb = NULL, .modedb_len = 0, .hfmin = 30000, .hfmax = 70000, .vfmin = 60, .vfmax = 60, .dclkmin = 6000000, .dclkmax = 28000000, .input = FB_DISP_RGB, }, .mode_screen = LCD_SCREEN_SX_N(320) | LCD_SCREEN_SY_N(240), .mode_horztiming = 0x00c4623b, .mode_verttiming = 0x00502814, .mode_clkcontrol = 0x00020002, /* /4=24Mhz */ .mode_pwmdiv = 0x00000000, .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, .mode_auxpll = 8, /* 96MHz AUXPLL */ .device_init = NULL, .device_shutdown = NULL, 320, 320, 240, 240, }, [1] = { /* VGA 640x480 H:30.3kHz V:58Hz */ .name = "VGA_640x480", .monspecs = { .modedb = NULL, .modedb_len = 0, .hfmin = 30000, .hfmax = 70000, .vfmin = 60, .vfmax = 60, .dclkmin = 6000000, .dclkmax = 28000000, .input = FB_DISP_RGB, }, .mode_screen = 0x13f9df80, .mode_horztiming = 0x003c5859, .mode_verttiming = 0x00741201, .mode_clkcontrol = 0x00020001, /* /4=24Mhz */ .mode_pwmdiv = 0x00000000, .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, .mode_auxpll = 8, /* 96MHz AUXPLL */ .device_init = NULL, .device_shutdown = NULL, 640, 480, 640, 480, }, [2] = { /* SVGA 800x600 H:46.1kHz V:69Hz */ .name = "SVGA_800x600", .monspecs = { .modedb = NULL, .modedb_len = 0, .hfmin = 30000, .hfmax = 70000, .vfmin = 60, .vfmax = 60, .dclkmin = 6000000, .dclkmax = 28000000, .input = FB_DISP_RGB, }, .mode_screen = 0x18fa5780, .mode_horztiming = 0x00dc7e77, .mode_verttiming = 0x00584805, .mode_clkcontrol = 0x00020000, /* /2=48Mhz */ .mode_pwmdiv = 0x00000000, .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, .mode_auxpll = 8, /* 96MHz AUXPLL */ .device_init = NULL, .device_shutdown = NULL, 800, 800, 600, 600, }, [3] = { /* XVGA 1024x768 H:56.2kHz V:70Hz */ .name = "XVGA_1024x768", .monspecs = { .modedb = NULL, .modedb_len = 0, .hfmin = 30000, .hfmax = 70000, .vfmin = 60, .vfmax = 60, .dclkmin = 6000000, .dclkmax = 28000000, .input = FB_DISP_RGB, }, .mode_screen = 0x1ffaff80, .mode_horztiming = 0x007d0e57, .mode_verttiming = 0x00740a01, .mode_clkcontrol = 0x000A0000, /* /1 */ .mode_pwmdiv = 0x00000000, .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, .mode_toyclksrc = 0x00000004, /* AUXPLL directly */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?