au1200fb.c
来自「Linux环境下视频显示卡设备的驱动程序源代码」· C语言 代码 · 共 1,922 行 · 第 1/4 页
C
1,922 行
.mode_backlight = 0x00000000, .mode_auxpll = 6, /* 72MHz AUXPLL */ .device_init = NULL, .device_shutdown = NULL, 1024, 1024, 768, 768, }, [4] = { /* XVGA XVGA 1280x1024 H:68.5kHz V:65Hz */ .name = "XVGA_1280x1024", .monspecs = { .modedb = NULL, .modedb_len = 0, .hfmin = 30000, .hfmax = 70000, .vfmin = 60, .vfmax = 60, .dclkmin = 6000000, .dclkmax = 28000000, .input = FB_DISP_RGB, }, .mode_screen = 0x27fbff80, .mode_horztiming = 0x00cdb2c7, .mode_verttiming = 0x00600002, .mode_clkcontrol = 0x000A0000, /* /1 */ .mode_pwmdiv = 0x00000000, .mode_pwmhi = 0x00000000, .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, .mode_auxpll = 10, /* 120MHz AUXPLL */ .device_init = NULL, .device_shutdown = NULL, 1280, 1280, 1024, 1024, }, [5] = { /* Samsung 1024x768 TFT */ .name = "Samsung_1024x768_TFT", .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 = 0x018cc677, .mode_verttiming = 0x00241217, .mode_clkcontrol = 0x00000000, /* SCB 0x1 /4=24Mhz */ .mode_pwmdiv = 0x8000063f, /* SCB 0x0 */ .mode_pwmhi = 0x03400000, /* SCB 0x0 */ .mode_outmask = 0x00FFFFFF, .mode_fifoctrl = 0x2f2f2f2f, .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, .mode_auxpll = 8, /* 96MHz AUXPLL */ .device_init = board_au1200fb_panel_init, .device_shutdown = board_au1200fb_panel_shutdown, 1024, 1024, 768, 768, }, [6] = { /* Toshiba 640x480 TFT */ .name = "Toshiba_640x480_TFT", .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(640) | LCD_SCREEN_SY_N(480), .mode_horztiming = LCD_HORZTIMING_HPW_N(96) | LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(51), .mode_verttiming = LCD_VERTTIMING_VPW_N(2) | LCD_VERTTIMING_VND1_N(11) | LCD_VERTTIMING_VND2_N(32), .mode_clkcontrol = 0x00000000, /* /4=24Mhz */ .mode_pwmdiv = 0x8000063f, .mode_pwmhi = 0x03400000, .mode_outmask = 0x00fcfcfc, .mode_fifoctrl = 0x2f2f2f2f, .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, .mode_auxpll = 8, /* 96MHz AUXPLL */ .device_init = board_au1200fb_panel_init, .device_shutdown = board_au1200fb_panel_shutdown, 640, 480, 640, 480, }, [7] = { /* Sharp 320x240 TFT */ .name = "Sharp_320x240_TFT", .monspecs = { .modedb = NULL, .modedb_len = 0, .hfmin = 12500, .hfmax = 20000, .vfmin = 38, .vfmax = 81, .dclkmin = 4500000, .dclkmax = 6800000, .input = FB_DISP_RGB, }, .mode_screen = LCD_SCREEN_SX_N(320) | LCD_SCREEN_SY_N(240), .mode_horztiming = LCD_HORZTIMING_HPW_N(60) | LCD_HORZTIMING_HND1_N(13) | LCD_HORZTIMING_HND2_N(2), .mode_verttiming = LCD_VERTTIMING_VPW_N(2) | LCD_VERTTIMING_VND1_N(2) | LCD_VERTTIMING_VND2_N(5), .mode_clkcontrol = LCD_CLKCONTROL_PCD_N(7), /*16=6Mhz*/ .mode_pwmdiv = 0x8000063f, .mode_pwmhi = 0x03400000, .mode_outmask = 0x00fcfcfc, .mode_fifoctrl = 0x2f2f2f2f, .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, .mode_auxpll = 8, /* 96MHz AUXPLL */ .device_init = board_au1200fb_panel_init, .device_shutdown = board_au1200fb_panel_shutdown, 320, 320, 240, 240, }, [8] = { /* Toppoly TD070WGCB2 7" 856x480 TFT */ .name = "Toppoly_TD070WGCB2", .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(856) | LCD_SCREEN_SY_N(480), .mode_horztiming = LCD_HORZTIMING_HND2_N(43) | LCD_HORZTIMING_HND1_N(43) | LCD_HORZTIMING_HPW_N(114), .mode_verttiming = LCD_VERTTIMING_VND2_N(20) | LCD_VERTTIMING_VND1_N(21) | LCD_VERTTIMING_VPW_N(4), .mode_clkcontrol = 0x00020001, /* /4=24Mhz */ .mode_pwmdiv = 0x8000063f, .mode_pwmhi = 0x03400000, .mode_outmask = 0x00fcfcfc, .mode_fifoctrl = 0x2f2f2f2f, .mode_toyclksrc = 0x00000004, /* AUXPLL directly */ .mode_backlight = 0x00000000, .mode_auxpll = 8, /* 96MHz AUXPLL */ .device_init = board_au1200fb_panel_init, .device_shutdown = board_au1200fb_panel_shutdown, 856, 856, 480, 480, },};#define NUM_PANELS (ARRAY_SIZE(known_lcd_panels))/********************************************************************/#ifdef CONFIG_PMstatic int set_brightness(unsigned int brightness){ unsigned int hi1, divider; /* limit brightness pwm duty to >= 30/1600 */ if (brightness < 30) { brightness = 30; } divider = (lcd->pwmdiv & 0x3FFFF) + 1; hi1 = (lcd->pwmhi >> 16) + 1; hi1 = (((brightness & 0xFF) + 1) * divider >> 8); lcd->pwmhi &= 0xFFFF; lcd->pwmhi |= (hi1 << 16); return brightness;}#endif /* CONFIG_PM */static int winbpp (unsigned int winctrl1){ int bits = 0; /* how many bits are needed for each pixel format */ switch (winctrl1 & LCD_WINCTRL1_FRM) { case LCD_WINCTRL1_FRM_1BPP: bits = 1; break; case LCD_WINCTRL1_FRM_2BPP: bits = 2; break; case LCD_WINCTRL1_FRM_4BPP: bits = 4; break; case LCD_WINCTRL1_FRM_8BPP: bits = 8; break; case LCD_WINCTRL1_FRM_12BPP: case LCD_WINCTRL1_FRM_16BPP655: case LCD_WINCTRL1_FRM_16BPP565: case LCD_WINCTRL1_FRM_16BPP556: case LCD_WINCTRL1_FRM_16BPPI1555: case LCD_WINCTRL1_FRM_16BPPI5551: case LCD_WINCTRL1_FRM_16BPPA1555: case LCD_WINCTRL1_FRM_16BPPA5551: bits = 16; break; case LCD_WINCTRL1_FRM_24BPP: case LCD_WINCTRL1_FRM_32BPP: bits = 32; break; } return bits;}static int fbinfo2index (struct fb_info *fb_info){ int i; for (i = 0; i < CONFIG_FB_AU1200_DEVS; ++i) { if (fb_info == (struct fb_info *)(&_au1200fb_devices[i].fb_info)) return i; } printk("au1200fb: ERROR: fbinfo2index failed!\n"); return -1;}static int au1200_setlocation (struct au1200fb_device *fbdev, int plane, int xpos, int ypos){ uint32 winctrl0, winctrl1, winenable, fb_offset = 0; int xsz, ysz; /* FIX!!! NOT CHECKING FOR COMPLETE OFFSCREEN YET */ winctrl0 = lcd->window[plane].winctrl0; winctrl1 = lcd->window[plane].winctrl1; winctrl0 &= (LCD_WINCTRL0_A | LCD_WINCTRL0_AEN); winctrl1 &= ~(LCD_WINCTRL1_SZX | LCD_WINCTRL1_SZY); /* Check for off-screen adjustments */ xsz = win->w[plane].xres; ysz = win->w[plane].yres; if ((xpos + win->w[plane].xres) > panel->Xres) { /* Off-screen to the right */ xsz = panel->Xres - xpos; /* off by 1 ??? */ /*printk("off screen right\n");*/ } if ((ypos + win->w[plane].yres) > panel->Yres) { /* Off-screen to the bottom */ ysz = panel->Yres - ypos; /* off by 1 ??? */ /*printk("off screen bottom\n");*/ } if (xpos < 0) { /* Off-screen to the left */ xsz = win->w[plane].xres + xpos; fb_offset += (((0 - xpos) * winbpp(lcd->window[plane].winctrl1))/8); xpos = 0; /*printk("off screen left\n");*/ } if (ypos < 0) { /* Off-screen to the top */ ysz = win->w[plane].yres + ypos; /* fixme: fb_offset += ((0-ypos)*fb_pars[plane].line_length); */ ypos = 0; /*printk("off screen top\n");*/ } /* record settings */ win->w[plane].xpos = xpos; win->w[plane].ypos = ypos; xsz -= 1; ysz -= 1; winctrl0 |= (xpos << 21); winctrl0 |= (ypos << 10); winctrl1 |= (xsz << 11); winctrl1 |= (ysz << 0); /* Disable the window while making changes, then restore WINEN */ winenable = lcd->winenable & (1 << plane); au_sync(); lcd->winenable &= ~(1 << plane); lcd->window[plane].winctrl0 = winctrl0; lcd->window[plane].winctrl1 = winctrl1; lcd->window[plane].winbuf0 = lcd->window[plane].winbuf1 = fbdev->fb_phys; lcd->window[plane].winbufctrl = 0; /* select winbuf0 */ lcd->winenable |= winenable; au_sync(); return 0;}static void au1200_setpanel (struct panel_settings *newpanel){ /* * Perform global setup/init of LCD controller */ uint32 winenable; /* Make sure all windows disabled */ winenable = lcd->winenable; lcd->winenable = 0; au_sync(); /* * Ensure everything is disabled before reconfiguring */ if (lcd->screen & LCD_SCREEN_SEN) { /* Wait for vertical sync period */ lcd->intstatus = LCD_INT_SS; while ((lcd->intstatus & LCD_INT_SS) == 0) { au_sync(); } lcd->screen &= ~LCD_SCREEN_SEN; /*disable the controller*/ do { lcd->intstatus = lcd->intstatus; /*clear interrupts*/ au_sync(); /*wait for controller to shut down*/ } while ((lcd->intstatus & LCD_INT_SD) == 0); /* Call shutdown of current panel (if up) */ /* this must occur last, because if an external clock is driving the controller, the clock cannot be turned off before first shutting down the controller. */ if (panel->device_shutdown != NULL) panel->device_shutdown(); } /* Newpanel == NULL indicates a shutdown operation only */ if (newpanel == NULL) return; panel = newpanel; printk("Panel(%s), %dx%d\n", panel->name, panel->Xres, panel->Yres); /* * Setup clocking if internal LCD clock source (assumes sys_auxpll valid) */ if (!(panel->mode_clkcontrol & LCD_CLKCONTROL_EXT)) { uint32 sys_clksrc; au_writel(panel->mode_auxpll, SYS_AUXPLL); sys_clksrc = au_readl(SYS_CLKSRC) & ~0x0000001f; sys_clksrc |= panel->mode_toyclksrc; au_writel(sys_clksrc, SYS_CLKSRC); } /* * Configure panel timings */ lcd->screen = panel->mode_screen; lcd->horztiming = panel->mode_horztiming; lcd->verttiming = panel->mode_verttiming; lcd->clkcontrol = panel->mode_clkcontrol; lcd->pwmdiv = panel->mode_pwmdiv; lcd->pwmhi = panel->mode_pwmhi; lcd->outmask = panel->mode_outmask; lcd->fifoctrl = panel->mode_fifoctrl; au_sync(); /* fixme: Check window settings to make sure still valid * for new geometry */#if 0 au1200_setlocation(fbdev, 0, win->w[0].xpos, win->w[0].ypos); au1200_setlocation(fbdev, 1, win->w[1].xpos, win->w[1].ypos); au1200_setlocation(fbdev, 2, win->w[2].xpos, win->w[2].ypos); au1200_setlocation(fbdev, 3, win->w[3].xpos, win->w[3].ypos);#endif lcd->winenable = winenable; /* * Re-enable screen now that it is configured */ lcd->screen |= LCD_SCREEN_SEN; au_sync(); /* Call init of panel */ if (panel->device_init != NULL) panel->device_init(); /* FIX!!!! not appropriate on panel change!!! Global setup/init */ lcd->intenable = 0; lcd->intstatus = ~0; lcd->backcolor = win->mode_backcolor; /* Setup Color Key - FIX!!! */ lcd->colorkey = win->mode_colorkey; lcd->colorkeymsk = win->mode_colorkeymsk; /* Setup HWCursor - FIX!!! Need to support this eventually */ lcd->hwc.cursorctrl = 0; lcd->hwc.cursorpos = 0; lcd->hwc.cursorcolor0 = 0; lcd->hwc.cursorcolor1 = 0; lcd->hwc.cursorcolor2 = 0; lcd->hwc.cursorcolor3 = 0;#if 0#define D(X) printk("%25s: %08X\n", #X, X) D(lcd->screen); D(lcd->horztiming); D(lcd->verttiming); D(lcd->clkcontrol); D(lcd->pwmdiv); D(lcd->pwmhi); D(lcd->outmask); D(lcd->fifoctrl); D(lcd->window[0].winctrl0); D(lcd->window[0].winctrl1); D(lcd->window[0].winctrl2); D(lcd->window[0].winbuf0); D(lcd->window[0].winbuf1); D(lcd->window[0].winbufctrl); D(lcd->window[1].winctrl0); D(lcd->window[1].winctrl1); D(lcd->window[1].winctrl2); D(lcd->window[1].winbuf0); D(lcd->window[1].winbuf1); D(lcd->window[1].winbufctrl); D(lcd->window[2].winctrl0); D(lcd->window[2].winctrl1); D(lcd->window[2].winctrl2); D(lcd->window[2].winbuf0); D(lcd->window[2].winbuf1); D(lcd->window[2].winbufctrl); D(lcd->window[3].winctrl0); D(lcd->window[3].winctrl1); D(lcd->window[3].winctrl2); D(lcd->window[3].winbuf0); D(lcd->window[3].winbuf1); D(lcd->window[3].winbufctrl); D(lcd->winenable); D(lcd->intenable); D(lcd->intstatus); D(lcd->backcolor); D(lcd->winenable); D(lcd->colorkey); D(lcd->colorkeymsk); D(lcd->hwc.cursorctrl); D(lcd->hwc.cursorpos); D(lcd->hwc.cursorcolor0); D(lcd->hwc.cursorcolor1); D(lcd->hwc.cursorcolor2); D(lcd->hwc.cursorcolor3);#endif}static void au1200_setmode(struct au1200fb_device *fbdev){ int plane = fbdev->plane; /* Window/plane setup */ lcd->window[plane].winctrl1 = ( 0 | LCD_WINCTRL1_PRI_N(plane) | win->w[plane].mode_winctrl1 /* FRM,CCO,PO,PIPE */ ) ; au1200_setlocation(fbdev, plane, win->w[plane].xpos, win->w[plane].ypos); lcd->window[plane].winctrl2 = ( 0 | LCD_WINCTRL2_CKMODE_00
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?