omap1710.h
来自「Linux Kernel 2.6.9 for OMAP1710」· C头文件 代码 · 共 411 行
H
411 行
/* * File: drivers/video/omap/omap1710.h * * This file is the header file for the OMAP1710 framebuffer. * * Copyright (C) 2001 RidgeRun, Inc. * Author: Alex McMains <aam@ridgerun.com> 2001/09/20 * Greg Lonnon <glonnon@ridgerun.com> * * Port to 2.6 framebuffer API: * Copyright (C) 2004 Dirk Behme * Author: Dirk Behme <dirk.behme@de.bosch.com> * * Added support for H3 * Copyright (C) 2004 Texas Instruments. * * 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. * * Please report all bugs and problems to the author. * */#ifndef _omap1710_h_#define _omap1710_h_static struct fb_info tifb_info;static u32 ti_pseudo_palette[17];static dma_addr_t dma_handle;static int tifb_enable = 1;extern int tps65010_set_gpio_out_value(int gpio, int value);#define NUM_XPIXELS 240#define NUM_YPIXELS 320#define BPP 16#define PALETTE_SIZE 32#define BPP_MASK 0x4000#define PAGE2_AUDIO_CODEC_REGISTERS 2 << 11#define LEAVE_CS 0x80/* We must reserve a whole page for the palette for consistent_alloc() */#define MAX_FRAMEBUFFER_SIZE (((NUM_XPIXELS) * (NUM_YPIXELS) * (BPP)/8) + \ (PAGE_SIZE))#define OMAP_LCD_NAME "omap-lcd"static DECLARE_COMPLETION(LcdDevObjectIsFree);static int tifb_probe(struct omap_dev *);static int tifb_remove(struct omap_dev *);#ifdef CONFIG_PMstatic int tifb_suspend(struct omap_dev *, u32);static int tifb_resume(struct omap_dev *);#else#define tifb_suspend NULL#define tifb_resume NULL#endif/* * Driver definition to register with the OMAP bus */static struct omap_driver lcd_omap_driver = { .drv = { .name = OMAP_LCD_NAME, }, .devid = OMAP_TIPB_DEVID_LCD, .busid = OMAP_BUS_TIPB, .clocks = 0, .probe = tifb_probe, .remove = tifb_remove,};/* * Device definition to match the driver above */static struct omap_dev lcd_omap_device = { .name = OMAP_LCD_NAME, .devid = OMAP_TIPB_DEVID_LCD, .busid = OMAP_BUS_TIPB, .mapbase = (void *)IO_ADDRESS(OMAP_LCD_BASE), .res = { .start = OMAP_LCD_BASE, .end = OMAP_LCD_BASE + OMAP_LCD_SIZE, }, .irq = { INT_LCD_CTRL, },};static struct fb_fix_screeninfo tifb_fix __initdata = { .id = "tifb", .smem_len = ((NUM_XPIXELS) * (NUM_YPIXELS) * (BPP)/8), .type = FB_TYPE_PACKED_PIXELS, .visual = FB_VISUAL_TRUECOLOR, .line_length = NUM_XPIXELS * (BPP/8), .accel = FB_ACCEL_NONE,};static struct fb_var_screeninfo tifb_var = { xres: NUM_XPIXELS, yres: NUM_YPIXELS, xres_virtual: NUM_XPIXELS, yres_virtual: NUM_YPIXELS, bits_per_pixel: 16, red: {11, 5, 0}, green: {5, 6, 0}, blue: {0, 5, 0}, activate: FB_ACTIVATE_NOW, height: -1, width: -1, accel_flags: 0, pixclock: 171521, left_margin: 64, right_margin: 64, upper_margin: 32, lower_margin: 32, hsync_len : 64, vsync_len: 2, sync: 0, vmode: FB_VMODE_NONINTERLACED};// LCD inlinesinline void LCD_WRITE(unsigned long v, unsigned long a) { outl((v),(IO_ADDRESS(a))); }inline unsigned long LCD_READ(unsigned long a) { return inl(IO_ADDRESS(a)); }static inline void omap_h3_hardware_enable(void){ int status; /* GPIO1 and GPIO2 of TPS65010 send LCD_ENBKL and LCD_ENVDD signals */ status = tps65010_set_gpio_out_value(1, 1); status += tps65010_set_gpio_out_value(2, 1); if (status != 0) DBG(KERN_WARNING "Unable to turn on LCD");}static inline void omap_h3_hardware_disable(void){ int status; /* GPIO1 and GPIO2 of TPS65010 send LCD_ENBKL and LCD_ENVDD signals */ status = tps65010_set_gpio_out_value(1, 0); status += tps65010_set_gpio_out_value(2, 0); if (status != 0) DBG(KERN_WARNING "Unable to turn off LCD");}static inline void hardware_enable(void){ /* initialize LCD */ omap_h3_hardware_enable(); /* According to the errata, if the framebuffer is in SDRAM, the max clock is 1/2 the TC clock rate. With 192 MHz use 1/3 TC clock rate. */ ck_set_rate(OMAP_LCD_CK, (ck_get_rate(OMAP_TC_CK) / 3)); DBG(KERN_INFO "TC_CK rate %d , LCD_CK rate %d\n", ck_get_rate(OMAP_TC_CK), ck_get_rate(OMAP_LCD_CK)); ck_enable(OMAP_LCD_CK);}static inline void hardware_disable(void){ /* stop LCD */ omap_h3_hardware_disable(); ck_disable(OMAP_LCD_CK);}static inline int lcd_active(void){ // Return true if LCD controller is running. return(LCD_READ(OMAP_LCD_CONTROL) & 1);}static inline void lcd_enable(void){ unsigned long value; hardware_enable(); // enable the LCD while (((value = LCD_READ(OMAP_LCD_CONTROL)) & 0x1) == 0) { LCD_WRITE(value | 0x1, OMAP_LCD_CONTROL); } DBG(KERN_INFO "LCD controller enabled\n");}void lcd_disable(void){ unsigned long value; unsigned long delay = jiffies + 10; // wait max .1 second // Clear the AutoIdle bit in the Global DMA control reg to work around the DMA // state machine bug in TI's errata doc. Have to do this to be able to stop and // restart the LCD controller reliably. We'll turn the bit back on in sys_idle. //omap_dma_autoidle_set(DISABLE_AUTOIDLE); // disable the LCD value = LCD_READ(OMAP_LCD_CONTROL); LCD_WRITE(value & ~0x1, OMAP_LCD_CONTROL); // Wait until current frame finished. Poll on LCDStatus[Done] bit. while (((LCD_READ(OMAP_LCD_STATUS) & 0x1) != 1) && (jiffies < delay)) { udelay(10); } DBG(KERN_INFO "LCD controller disabled\n");}#ifdef FB_DEBUGstatic inline void print_lcd_regs(void){ DBG(KERN_INFO "print_lcd_regs:\n"); DBG(KERN_INFO "OMAP1710: control 0x%8.8x status 0x%8.8x timing0 0x%8.8x" " timing1 0x%8.8x timing2 0x%8.8x\n", (int)LCD_READ(OMAP_LCD_CONTROL), (int)LCD_READ(OMAP_LCD_STATUS), (int)LCD_READ(OMAP_LCD_TIMING0), (int)LCD_READ(OMAP_LCD_TIMING1), (int)LCD_READ(OMAP_LCD_TIMING2));}#elsestatic inline void print_lcd_regs(void) {}#endifstatic void tifb_init_dma(void){ unsigned long dma_base = dma_handle + PAGE_SIZE - PALETTE_SIZE; unsigned long size = NUM_XPIXELS * NUM_YPIXELS * BPP/8 + PALETTE_SIZE; omap_set_lcd_dma_b1(dma_base, 8, size / (8 * 4), OMAP_DMA_DATA_TYPE_S32); omap_start_lcd_dma(); DBG(KERN_INFO "tifb_init_dma: base=0x%08lx\n", dma_base); DBG(KERN_INFO "tifb_init_dma: size=%d\n", size);}static void __init tifb_init_registers(void){ unsigned long value; DBG(KERN_INFO "tifb_init_registers\n"); // setup the LCD Control value = 0; value |= (1 << 24); // 12 BPP mode (off) value |= (0 << 23); // TFT map value |= (0 << 22); // LCD control bit 1 value |= (0 << 20); // palette and data loading value |= (0 << 12); // FDD to 16 wait cycles value |= (1 << 9); // use 8 pixel pins value |= (0 << 8); // LCD control bit 0 value |= (1 << 7); // tft value |= (0 << 4); // if 0 disables the palette interrupt value |= (0 << 3); // if 0 disables the done interrupt (set by DMA controller after last transfer has finished if LCD controller is disabled) value |= (0 << 1); // LCD Monochrome (Colour mode) value |= (0 << 0); // LCD enable (is done later, so here 0) LCD_WRITE(value, OMAP_LCD_CONTROL); // setup the Timing0 value = 0; value |= ((71-12) << 24); // H Back Porch is 71-12 value |= (13 << 16); // H Front Porch is 13 value |= (11 << 10); // HSW width for LCD is 11 value |= NUM_XPIXELS -1; // current_par.xres -1; LCD_WRITE(value, OMAP_LCD_TIMING0); // setup the Timing1 value = 0; value |= (0 << 24); // Back Porch (not used) value |= (1 << 16); // Front Porch (not used) value |= (0 << 10); // VSW width for the LCD is 1 (minus 1) value |= NUM_YPIXELS - 1; // current_par.yres - 1; LCD_WRITE(value, OMAP_LCD_TIMING1); // setup the Timing2 value = 0; value |= ( 0 << 25); // PHSVS On_Off value |= ( 0 << 24); // PHSVS RF value |= ( 0 << 23); // IEO value |= ( 0 << 22); // IPC value |= ( 0 << 21); // IHS value |= ( 0 << 20); // IVS value |= ( 0 << 16); // ACBI this should be disabled value |= (255 << 8); // ACB value |= ( 4 << 0); // PCD (2 = max frequency seems to be a little bit to fast) LCD_WRITE(value, OMAP_LCD_TIMING2); // setup the LCD Subpanel value = 0; value |= (0 << 31); // SPEN value |= (0 << 29); // HOLS value |= (0 << 16); // LPPT value |= (0 << 0); // DPD LCD_WRITE(value, OMAP_LCD_SUBPANEL); // setup dma tifb_init_dma(); print_lcd_regs();}static void lcd_dma_handler(u16 status, void *dummy){} static irqreturn_t lcd_irq_handler(int irq, void *dummy, struct pt_regs *fp){ unsigned long status; int reset = 0; static int abc = 0; static int fuf = 0; static int sync = 0; static int done = 0; status = LCD_READ(OMAP_LCD_STATUS); /* Without any problems, the debug messages in this function are never printed */ DBG(KERN_INFO "lcd_irq_handler: IRQ Nr.: %d, LCD status reg: 0x%04lx\n", irq, status); if ( status & (1<<3) ) { printk(KERN_INFO "LCD AC BIAS counter has reached zero\n"); status &= (1<<3); LCD_WRITE(status, OMAP_LCD_STATUS); abc++; } if ( status & (1<<5) ) { printk(KERN_WARNING "LCD FIFO underrun interrupt\n"); reset = 1; fuf++; } if ( status & (1<<2) ) { /* This message may be printed once at system startup ... */ DBG(KERN_WARNING "ERROR: LCD sync interrupt\n"); reset = 1; sync++; } if ( status & (1<<0) ) { DBG(KERN_INFO "LCD DONE interrupt: LCD controller is stopped!\n"); reset = 1; done++; } if ( (sync % 1024) == 0 ) { printk(KERN_INFO "LCD interrupt status: abc %d fuf %d sync %d done %d\n",abc, fuf, sync, done); print_lcd_regs(); } if ( reset ) { // This will clear the error condition and restart the LCD // If we are here and LCD hasn't stopped, stop it if(lcd_active()) { lcd_disable(); } lcd_enable(); } /* FIXME! Was it really ours? */ return IRQ_HANDLED;}#endif /* _omap1710_h_ */
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?