📄 pxafb.c.svn-base
字号:
/* * (C) Copyright 2001-2002 * Wolfgang Denk, DENX Software Engineering -- wd@denx.de * * See file CREDITS for list of people who contributed to this * project. * * 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 program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * 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., 59 Temple Place, Suite 330, Boston, * MA 02111-1307 USA *//************************************************************************//* ** HEADER FILES *//************************************************************************/#define DEBUG 1#include <config.h>#include <common.h>#include <version.h>#include <stdarg.h>#include <lcdvideo.h>#include <linux/types.h>#include <devices.h>#include <asm/arch/pxa-regs.h>#ifdef CONFIG_LCD/************************************************************************//* ** CONFIG STUFF -- should be moved to board config file *//************************************************************************/#ifndef CONFIG_EDT32F10#define CONFIG_LCD_LOGO#define LCD_INFO /* Display Logo, (C) and system info */#endif#ifdef CONFIG_V37#undef CONFIG_LCD_LOGO#undef LCD_INFO#endif#undef CONFIG_LCD_LOGO#define LCD_TEST_PATTERN/* #define LCD_TEST_PATTERN */ /* color backgnd for frame/color adjust *//* #define CFG_INVERT_COLORS */ /* Not needed - adjust vl_dp instead *//************************************************************************//************************************************************************//* ** FONT AND LOGO DATA *//************************************************************************/#include <video_font.h> /* Get font data, width and height */#ifdef CONFIG_LCD_LOGO# include <bmp_nexus.h> /* Get logo data, width and height */#endif/************************************************************************//************************************************************************//* * Information about displays we are using. This is for configuring * the LCD controller and memory allocation. Someone has to know what * is connected, as we can't autodetect anything. */#define CFG_HIGH 0 /* Pins are active high */#define CFG_LOW 1 /* Pins are active low *//* PXA LCD DMA descriptor */struct pxafb_dma_descriptor { u_long fdadr; u_long fsadr; u_long fidr; u_long ldcmd;};/* PXA LCD info */struct pxafb_info { /* Misc registers */ u_long reg_lccr3; u_long reg_lccr2; u_long reg_lccr1; u_long reg_lccr0; u_long fdadr0; u_long fdadr1; /* DMA descriptors */ struct pxafb_dma_descriptor * dmadesc_fblow; struct pxafb_dma_descriptor * dmadesc_fbhigh; struct pxafb_dma_descriptor * dmadesc_palette; u_long screen; /* physical address of frame buffer */ u_long palette; /* physical address of palette memory */ u_int palette_size;};typedef struct vidinfo { ushort vl_col; /* Number of columns (i.e. 640) */ ushort vl_row; /* Number of rows (i.e. 480) */ ushort vl_width; /* Width of display area in millimeters */ ushort vl_height; /* Height of display area in millimeters */ /* LCD configuration register. */ u_char vl_clkp; /* Clock polarity */ u_char vl_oep; /* Output Enable polarity */ u_char vl_hsp; /* Horizontal Sync polarity */ u_char vl_vsp; /* Vertical Sync polarity */ u_char vl_dp; /* Data polarity */ u_char vl_bpix; /* Bits per pixel, 0 = 1, 1 = 2, 2 = 4, 3 = 8, 4 = 16 */ u_char vl_lbw; /* LCD Bus width, 0 = 4, 1 = 8 */ u_char vl_splt; /* Split display, 0 = single-scan, 1 = dual-scan */ u_char vl_clor; /* Color, 0 = mono, 1 = color */ u_char vl_tft; /* 0 = passive, 1 = TFT */ /* Horizontal control register. Timing from data sheet. */ ushort vl_hpw; /* Horz sync pulse width */ u_char vl_blw; /* Wait before of line */ u_char vl_elw; /* Wait end of line */ /* Vertical control register. */ u_char vl_vpw; /* Vertical sync pulse width */ u_char vl_bfw; /* Wait before of frame */ u_char vl_efw; /* Wait end of frame */ u_char vl_lcdac; /* LCD AC timing */ /* PXA LCD controller params */ struct pxafb_info pxa;} vidinfo_t;#define LCD_MONOCHROME 0#define LCD_COLOR2 1#define LCD_COLOR4 2#define LCD_COLOR8 3#define LCD_COLOR16 4/*----------------------------------------------------------------------*/#define CONFIG_PXA_VGA#ifdef CONFIG_PXA_VGA/* * LCD outputs connected to a video DAC */#define LCD_BPP LCD_COLOR8/* you have to set lccr0 and lccr3 (including pcd) */#define REG_LCCR0 0x003008f8#define REG_LCCR3 0x0300FF01/* 640x480x16 @ 61 Hz */static vidinfo_t panel_info = { vl_col: 640, vl_row: 480, vl_width: 640, vl_height: 480, vl_clkp: CFG_HIGH, vl_oep: CFG_HIGH, vl_hsp: CFG_HIGH, vl_vsp: CFG_HIGH, vl_dp: CFG_HIGH, vl_bpix: LCD_BPP, vl_lbw: 0, vl_splt: 0, vl_clor: 0, vl_lcdac: 0, vl_tft: 1, vl_hpw: 40, vl_blw: 56, vl_elw: 56, vl_vpw: 20, vl_bfw: 8, vl_efw: 8,};#endif /* CONFIG_PXA_VIDEO */#ifdef CONFIG_SHARP_LM8V31#define LCD_BPP LCD_COLOR8#define LCD_INVERT_COLORS /* Needed for colors to be correct, but why? *//* you have to set lccr0 and lccr3 (including pcd) */#define REG_LCCR0 0x0030087C#define REG_LCCR3 0x0340FF08static vidinfo_t panel_info = { vl_col: 640, vl_row: 480, vl_width: 157, vl_height: 118, vl_clkp: CFG_HIGH, vl_oep: CFG_HIGH, vl_hsp: CFG_HIGH, vl_vsp: CFG_HIGH, vl_dp: CFG_HIGH, vl_bpix: LCD_BPP, vl_lbw: 0, vl_splt: 1, vl_clor: 1, vl_lcdac: 0, vl_tft: 0, vl_hpw: 1, vl_blw: 3, vl_elw: 3, vl_vpw: 1, vl_bfw: 0, vl_efw: 0,};#endif /* CONFIG_SHARP_LM8V31 *//*----------------------------------------------------------------------*//*----------------------------------------------------------------------*/#if defined(LCD_INFO_BELOW_LOGO)# define LCD_INFO_X 0# define LCD_INFO_Y (BMP_LOGO_HEIGHT + VIDEO_FONT_HEIGHT)#elif defined(CONFIG_LCD_LOGO)# define LCD_INFO_X (BMP_LOGO_WIDTH + 4 * VIDEO_FONT_WIDTH)# define LCD_INFO_Y (VIDEO_FONT_HEIGHT)#else# define LCD_INFO_X (VIDEO_FONT_WIDTH)# define LCD_INFO_Y (VIDEO_FONT_HEIGHT)#endif#ifndef LCD_BPP#define LCD_BPP LCD_COLOR8#endif#ifndef LCD_DF#define LCD_DF 1#endif#define NBITS(bit_code) (1 << (bit_code))#define NCOLORS(bit_code) (1 << NBITS(bit_code))static int lcd_line_length;static int lcd_color_fg;static int lcd_color_bg;static char lcd_is_enabled = 0; /* Indicate that LCD is enabled *//* * Frame buffer memory information */static void *lcd_base; /* Start of framebuffer memory */static void *lcd_console_address; /* Start of console buffer *//************************************************************************//* ** CONSOLE CONSTANTS *//************************************************************************/#if LCD_BPP == LCD_MONOCHROME/* * Simple color definitions */#define CONSOLE_COLOR_BLACK 0#define CONSOLE_COLOR_WHITE 1 /* Must remain last / highest */#elif LCD_BPP == LCD_COLOR8/* * Simple color definitions */#define CONSOLE_COLOR_BLACK 0#define CONSOLE_COLOR_RED 1#define CONSOLE_COLOR_GREEN 2#define CONSOLE_COLOR_YELLOW 3#define CONSOLE_COLOR_BLUE 4#define CONSOLE_COLOR_MAGENTA 5#define CONSOLE_COLOR_CYAN 6#define CONSOLE_COLOR_GREY 14#define CONSOLE_COLOR_WHITE 15 /* Must remain last / highest */#else /* 16 bit */#define CONSOLE_COLOR_BLACK 0x0000#define CONSOLE_COLOR_WHITE 0xffff /* Must remain last / highest */#endif#if defined(CONFIG_LCD_LOGO) && (CONSOLE_COLOR_WHITE >= BMP_LOGO_OFFSET)#error Default Color Map overlaps with Logo Color Map#endif/************************************************************************/#ifndef PAGE_SIZE#define PAGE_SIZE 4096#endif/************************************************************************//* ** CONSOLE DEFINITIONS & FUNCTIONS *//************************************************************************/#if defined(CONFIG_LCD_LOGO) && !defined(LCD_INFO_BELOW_LOGO)#define CONSOLE_ROWS ((panel_info.vl_row-BMP_LOGO_HEIGHT) \ / VIDEO_FONT_HEIGHT)#else#define CONSOLE_ROWS (panel_info.vl_row / VIDEO_FONT_HEIGHT)#endif#define CONSOLE_COLS (panel_info.vl_col / VIDEO_FONT_WIDTH)#define CONSOLE_ROW_SIZE (VIDEO_FONT_HEIGHT * lcd_line_length)#define CONSOLE_ROW_FIRST (lcd_console_address)#define CONSOLE_ROW_SECOND (lcd_console_address + CONSOLE_ROW_SIZE)#define CONSOLE_ROW_LAST (lcd_console_address + CONSOLE_SIZE \ - CONSOLE_ROW_SIZE)#define CONSOLE_SIZE (CONSOLE_ROW_SIZE * CONSOLE_ROWS)#define CONSOLE_SCROLL_SIZE (CONSOLE_SIZE - CONSOLE_ROW_SIZE)#if LCD_BPP == LCD_MONOCHROME#define COLOR_MASK(c) ((c) | (c) << 1 | (c) << 2 | (c) << 3 | \ (c) << 4 | (c) << 5 | (c) << 6 | (c) << 7)#elif LCD_BPP == LCD_COLOR8#define COLOR_MASK(c) (c)#elif LCD_BPP == LCD_COLOR16#define COLOR_MASK(c) (c)#else#error Unsupported LCD BPP.#endifstatic short console_col;static short console_row;/************************************************************************/ulong lcd_setmem (ulong addr);static void lcd_drawchars (ushort x, ushort y, uchar *str, int count);static inline void lcd_puts_xy (ushort x, ushort y, uchar *s);static inline void lcd_putc_xy (ushort x, ushort y, uchar c);static int lcd_init (void *lcdbase);static void lcd_ctrl_init (void *lcdbase);static void lcd_enable (void);static void *lcd_logo (void);#if LCD_BPP == LCD_COLOR8static void lcd_setcolreg (ushort regno, ushort red, ushort green, ushort blue);#endif#if LCD_BPP == LCD_MONOCHROMEstatic void lcd_initcolregs (void);#endifstatic void lcd_setfgcolor (int color);static void lcd_setbgcolor (int color);#ifdef NOT_USED_SO_FARstatic int lcd_getbgcolor (void);static void lcd_disable (void);static void lcd_getcolreg (ushort regno, ushort *red, ushort *green, ushort *blue);static int lcd_getfgcolor (void);#endif /* NOT_USED_SO_FAR */static int pxafb_init_mem(void *lcdbase, vidinfo_t *vid);static void pxafb_setup_gpio(vidinfo_t *vid);static void pxafb_enable_controller(vidinfo_t *vid);static int pxafb_init(vidinfo_t *vid);/************************************************************************//*----------------------------------------------------------------------*/static void console_scrollup (void){ /* Copy up rows ignoring the first one */ memcpy (CONSOLE_ROW_FIRST, CONSOLE_ROW_SECOND, CONSOLE_SCROLL_SIZE); /* Clear the last one */ memset (CONSOLE_ROW_LAST, COLOR_MASK(lcd_color_bg), CONSOLE_ROW_SIZE);}/*----------------------------------------------------------------------*/static inline void console_back (void){ if (--console_col < 0) { console_col = CONSOLE_COLS-1 ; if (--console_row < 0) { console_row = 0; } } lcd_putc_xy (console_col * VIDEO_FONT_WIDTH, console_row * VIDEO_FONT_HEIGHT, ' ');}/*----------------------------------------------------------------------*/static inline void console_newline (void){ ++console_row; console_col = 0; /* Check if we need to scroll the terminal */ if (console_row >= CONSOLE_ROWS) { /* Scroll everything up */ console_scrollup () ; --console_row; }}/*----------------------------------------------------------------------*/void lcd_putc (const char c){ if (!lcd_is_enabled) { serial_putc(c); return; } switch (c) { case '\r': console_col = 0; return; case '\n': console_newline(); return; case '\t': /* Tab (8 chars alignment) */ console_col |= 8; console_col &= ~7; if (console_col >= CONSOLE_COLS) { console_newline(); } return; case '\b': console_back(); return; default: lcd_putc_xy (console_col * VIDEO_FONT_WIDTH, console_row * VIDEO_FONT_HEIGHT, c); if (++console_col >= CONSOLE_COLS) { console_newline(); } return; } /* NOTREACHED */}/*----------------------------------------------------------------------*/void lcd_puts (const char *s){ if (!lcd_is_enabled) { serial_puts (s); return; } while (*s) { lcd_putc (*s++); }}/************************************************************************//* ** Low-Level Graphics Routines *//************************************************************************/static void lcd_drawchars (ushort x, ushort y, uchar *str, int count){ uchar *dest; ushort off, row; dest = (uchar *)(lcd_base + y * lcd_line_length + x * (1 << LCD_BPP) / 8); off = x * (1 << LCD_BPP) % 8; for (row=0; row < VIDEO_FONT_HEIGHT; ++row, dest += lcd_line_length) { uchar *s = str; uchar *d = dest; int i;#if LCD_BPP == LCD_MONOCHROME uchar rest = *d & -(1 << (8-off)); uchar sym;#endif for (i=0; i<count; ++i) { uchar c, bits; c = *s++; bits = video_fontdata[c * VIDEO_FONT_HEIGHT + row];#if LCD_BPP == LCD_MONOCHROME sym = (COLOR_MASK(lcd_color_fg) & bits) | (COLOR_MASK(lcd_color_bg) & ~bits); *d++ = rest | (sym >> off); rest = sym << (8-off);#elif LCD_BPP == LCD_COLOR8 for (c=0; c<8; ++c) { *d++ = (bits & 0x80) ? lcd_color_fg : lcd_color_bg; bits <<= 1; }#elif LCD_BPP == LCD_COLOR16 for (c=0; c<16; ++c) { *d++ = (bits & 0x80) ? lcd_color_fg : lcd_color_bg; bits <<= 1; }#endif }#if LCD_BPP == LCD_MONOCHROME *d = rest | (*d & ((1 << (8-off)) - 1));#endif }}/*----------------------------------------------------------------------*/static inline void lcd_puts_xy (ushort x, ushort y, uchar *s){#if defined(CONFIG_LCD_LOGO) && !defined(LCD_INFO_BELOW_LOGO) lcd_drawchars (x, y+BMP_LOGO_HEIGHT, s, strlen (s));#else lcd_drawchars (x, y, s, strlen (s));#endif}/*----------------------------------------------------------------------*/static inline void lcd_putc_xy (ushort x, ushort y, uchar c)
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -