📄 davincifb.c
字号:
dispc_reg_out(VENC_VSTART,0x15); dispc_reg_out(VENC_VSTARTA,0x15);
dispc_reg_out(VENC_HINT,1350); //1100@@@@@@@@@@@@@@@@@@@@@@@@@@@@ dispc_reg_out(VENC_VINT,1150); //850 @@@@@@@@@@@@@@@@@@@@@@@@@@@ dispc_reg_out(VENC_VSPLS,20); dispc_reg_out(VENC_HSPLS,30);
/*设置为并行RGB输出,standed模式(PAL、NTSC)时序*/
dispc_reg_out(VENC_VMOD, 0x2013); //0x2013设置为非标准模式时序,设置为2003,小屏幕即可输出 dispc_reg_out(VENC_DCLKCTL,0x801); //0x800, dispc_reg_out(VENC_DCLKPTN0,0x3); dispc_reg_out(VENC_DCLKPTN0A,0x3); dispc_reg_out(VENC_OSDCLK0,0x3); dispc_reg_out(VENC_OSDCLK1,0xf);
/*设置VIDCTL寄存器*/
dispc_reg_out(VENC_VIDCTL, 0x2000);
/*设置SYNCCTL寄存器*/
dispc_reg_out(VENC_SYNCCTL, 0x3);
/*设置LCDOUT寄存器*/
dispc_reg_out(VENC_LCDOUT, 0x01); //0x1使能LCD_OE的输出 //dispc_reg_out(VENC_VDPRO, 0x2b70); //shezhi VDPRO
}
else
{
dispc_reg_out(VENC_VMOD, 0);
}
}static inline void fix_default_var(struct dm_win_info *w, u32 xres, u32 yres, u32 xpos, u32 ypos, int n_buf) //设定fb_var_screeninfo的默认值{ struct fb_var_screeninfo *v = &w->info.var; v->xres = xres; v->yres = yres; v->xres_virtual = v->xres; v->yres_virtual = v->yres * n_buf; x_pos(w) = xpos; y_pos(w) = ypos;} static void dm64xxfb_cleanup(void); /* * Initialization */int __init dm64xxfb_init(void) //初始化 fb{
int i;
printk(" \n--->5\n--->\n---->\n------>\nNow Enter davinci dm64xxfb_init()!\n");
struct fb_info *info; DBGENTER; if (dmparams.windows == 0) return 0; /* user disabled all windows through bootargs */ dm.mmio_base_phys = OSD_REG_BASE;
dm.mmio_size = OSD_REG_SIZE; /* request the mem regions */#ifdef REVISIT if (!request_mem_region(dm.mmio_base_phys, dm.mmio_size, DRIVER)) { printk(KERN_ERR DRIVER ": cannot reserve MMIO region\n"); RETURN(-ENODEV); } /* map the regions */ dm.mmio_base = (unsigned long) ioremap(dm.mmio_base_phys, dm.mmio_size); if (!dm.mmio_base) { printk(KERN_ERR DRIVER ": cannot map MMIO\n"); goto release_mmio; }#endif /* initialize the vsync wait queue */ init_waitqueue_head(&dm.vsync_wait); dm.timeout = HZ/5;
if ((dmparams.output == NTSC) && (dmparams.format == COMPOSITE)) dm.output_device_config = dm64xxfb_ntsc_composite_config; else if ((dmparams.output == NTSC) && (dmparams.format == SVIDEO)) dm.output_device_config = dm64xxfb_ntsc_svideo_config; else if ((dmparams.output == NTSC) && (dmparams.format == COMPONENT)) dm.output_device_config = dm64xxfb_ntsc_component_config; else if ((dmparams.output == PAL) && (dmparams.format == COMPOSITE)) dm.output_device_config = dm64xxfb_pal_composite_config; else if ((dmparams.output == PAL) && (dmparams.format == SVIDEO)) dm.output_device_config = dm64xxfb_pal_svideo_config; else if ((dmparams.output == PAL) && (dmparams.format == COMPONENT)) dm.output_device_config = dm64xxfb_pal_component_config; else if(dmparams.output == LCDS)
{
dm.output_device_config = dm64xxfb_lcd_config;
printk("Now Enter LCD display mode!\n");
}
else { printk(KERN_WARNING "Unsupported output device!\n");//在这里添加初始化LCD输出的代码,照着上面的例子写 dm.output_device_config = NULL; }
printk("Setting Up Clocks for DM420 OSD\n"); /* Initialize the VPSS Clock Control register */ dispc_reg_out(VPSS_CLKCTL, 0x19); //*****0x18 ,0x19 clk frequence is54M Hz //设置VPSS的时钟控制,若设为0x18则开放DAC的时钟 dispc_reg_merge(PLLCTL,0xff,0);
dispc_reg_out(PLLDIV1,0x0000); dispc_reg_out(PLLDIV1,0x8002);dispc_reg_merge(PLLCTL,0x00,0); //这几句是先关闭PLL2,然后设置PLLDIV1为2,然后打开PLL2,打开和关闭的语法有问题,可是结果是正确的,可能有其他的地方修改了此关闭与启动...
printk("(((((((((((EER=%x\n",dispc_reg_in(EER));printk("(((((((((((EERH=%x\n",dispc_reg_in(EERH));printk("(((((((((((EECR=%x\n",dispc_reg_in(EECR));printk("(((((((((((EECRH=%x\n",dispc_reg_in(EECRH));printk("(((((((((((EESR=%x\n",dispc_reg_in(EESR));printk("(((((((((((EESRH=%x\n",dispc_reg_in(EESRH));/*printk("&&&&&&&&SDRCR=%x\n",dispc_reg_in(DDR_SDRCR));printk("&&&&&&&&SDBCR=%x\n",dispc_reg_in(DDR_SDBCR));printk("&&&&&&&&SDRSTAT=%x\n",dispc_reg_in(DDR_SDRSTAT));printk("&&&&&&&&DDRPHYCR=%x\n",dispc_reg_in(DDR_DDRPHYCR));asm(mov PLLCTL,0);/*for(i=0;i<100000;i++)if(i%10000==0)printk("++++++++++\n");dispc_reg_merge(DDR_SDRCR,0xffffffff,1<<31);dispc_reg_merge(DDR_SDRCR,0xffffffff,1<<30);dispc_reg_merge(DDR_SDRSTAT,0,1<<2);dispc_reg_merge(DDR_DDRPHYCR,0xff,1<<4);dispc_reg_merge(PLLCTL,0xff,0);dispc_reg_out(PLLM,0x0000);dispc_reg_out(PLLM,0x800b);dispc_reg_out(PLLDIV1,0x0000);dispc_reg_out(PLLDIV1,0x8005);dispc_reg_out(PLLDIV2,0x0000);dispc_reg_out(PLLDIV2,0x8000);dispc_reg_merge(PLLCTL,0xff,1<<4);for(i=0;i<2000;i++);dispc_reg_merge(PLLCTL,0x00,0);dispc_reg_merge(DDR_DDRPHYCR,0x00,1<<4);dispc_reg_merge(DDR_DDRPHYCR,0xff,1<<5);dispc_reg_merge(DDR_SDRSTAT,0xff,1<<2);for(i=0;i<1000;i++);dispc_reg_merge(DDR_SDBCR,0xffff,1<<15);dispc_reg_merge(DDR_SDRCR,0x00000000,1<<30);dispc_reg_merge(DDR_SDRCR,0x00000000,1<<31);for(i=0;i<1000;i++);*/ /* Set Base Pixel X and Base Pixel Y */ dispc_reg_out(OSD_BASEPX, BASEX); //设置了图像参考的点 dispc_reg_out(OSD_BASEPY, BASEY); /* Reset OSD registers to default. */ dispc_reg_out(OSD_MODE, 0); dispc_reg_out(OSD_OSDWIN0MD, 0);//REVISIT: should we reset the other window modes too? /* Set blue background color */ set_bg_color(0, 162); /* Field Inversion Workaround */ dispc_reg_out(OSD_MODE, 0x200); //翻转场信号// printk("-------------- VID0 -----------------\n"); if (!dmparams.windows & (1 << VID0)) {
printk(KERN_WARNING "No video/osd windows will be enabled "
"because Video0 is disabled\n");
return 0; /* background will still be shown */
}
/* Setup VID0 framebuffer */
if (!mem_alloc(&dm.vid0, VID0_FB_PHY, VID0_FB_SIZE, VID0_FBNAME)) {
dm.vid0->dm = &dm;
fix_default_var(dm.vid0,
dmparams.vid0_xres, dmparams.vid0_yres,
dmparams.vid0_xpos, dmparams.vid0_ypos,
TRIPLE_BUF);
info = init_fb_info(dm.vid0, &vid0_default_var, VID0_FBNAME);
if (dm64xxfb_check_var(&info->var, info)) {
printk(KERN_ERR VID0_FBNAME
": invalid default video mode\n");
goto exit;
}
memset((void *)dm.vid0->fb_base, 0xb4, dm.vid0->fb_size);
} else
goto exit; // printk("-------------- OSD0 -----------------\n"); /* Setup OSD0 framebuffer */ if ((dmparams.windows & (1 << OSD0)) && (!mem_alloc(&dm.osd0, OSD0_FB_PHY, OSD0_FB_SIZE, OSD0_FBNAME))) { printk("-------------- OSD0 -----------------\n"); dm.osd0->dm = &dm; fix_default_var(dm.osd0, dmparams.osd0_xres, dmparams.osd0_yres, dmparams.osd0_xpos, dmparams.osd0_ypos, DOUBLE_BUF); info = init_fb_info(dm.osd0, &osd0_default_var, OSD0_FBNAME); if (dm64xxfb_check_var(&info->var, info)) { printk(KERN_ERR OSD0_FBNAME ": invalid default video mode\n"); mem_release(dm.osd0); } else memset((void *)dm.osd0->fb_base, 0, dm.osd0->fb_size); } // printk("-------------- OSD1 -----------------\n"); /* Setup OSD1 framebuffer */ if ((dmparams.windows & (1 << OSD1)) && (!mem_alloc(&dm.osd1, OSD1_FB_PHY, OSD1_FB_SIZE, OSD1_FBNAME))) { dm.osd1->dm = &dm; fix_default_var(dm.osd1, dmparams.osd1_xres, dmparams.osd1_yres, dmparams.osd1_xpos, dmparams.osd1_ypos, DOUBLE_BUF); info = init_fb_info(dm.osd1, &osd1_default_var, OSD1_FBNAME); if (dm64xxfb_check_var(&info->var, info)) { printk(KERN_ERR OSD1_FBNAME ": invalid default video mode\n"); mem_release(dm.osd1); } else /* Set blend factor to show OSD windows */ memset((void *)dm.osd1->fb_base, 0xff,dm.osd1->fb_size); }// printk("-------------- VID1 -----------------\n"); //setup VID1的FB,并根据dmparams中的值初始化此fb的var /* Setup VID1 framebuffer */ if ((dmparams.windows & (1 << VID1)) && (!mem_alloc(&dm.vid1, VID1_FB_PHY, VID1_FB_SIZE, VID1_FBNAME))) { dm.vid1->dm = &dm; fix_default_var(dm.vid1, dmparams.vid1_xres, dmparams.vid1_yres, dmparams.vid1_xpos, dmparams.vid1_ypos, TRIPLE_BUF); info = init_fb_info(dm.vid1, &vid1_default_var, VID1_FBNAME); if (dm64xxfb_check_var(&info->var, info)) { printk(KERN_ERR VID1_FBNAME ": invalid default video mode\n"); mem_release(dm.vid1); } else memset((void *)dm.vid1->fb_base, 0x88,dm.vid1->fb_size); }printk("222222(((((((((((EER=%x\n",dispc_reg_in(EER));printk("(((((((((((EERH=%x\n",dispc_reg_in(EERH));printk("(((((((((((EECR=%x\n",dispc_reg_in(EECR));printk("(((((((((((EECRH=%x\n",dispc_reg_in(EECRH));printk("(((((((((((EESR=%x\n",dispc_reg_in(EESR));printk("(((((((((((EESRH=%x\n",dispc_reg_in(EESRH)); /* Register OSD0 framebuffer */ if (dm.osd0) { info = &dm.osd0->info; if (register_framebuffer(info) < 0) { printk(KERN_ERR OSD0_FBNAME "Unable to register OSD0 framebuffer\n"); mem_release(dm.osd0); } else { printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); dm64xxfb_set_par(info); } } /* Register VID0 framebuffer */ info = &dm.vid0->info; if (register_framebuffer(info) < 0) { printk(KERN_ERR VID0_FBNAME "Unable to register VID0 framebuffer\n"); goto exit; } else { printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); dm64xxfb_set_par(info); } /* Register OSD1 framebuffer */ if (dm.osd1) { info = &dm.osd1->info; if (register_framebuffer(info) < 0) { printk(KERN_ERR OSD1_FBNAME "Unable to register OSD1 framebuffer\n"); mem_release(dm.osd1); } else { printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); dm64xxfb_set_par(info); } } /* Register VID1 framebuffer */ if (dm.vid1) { info = &dm.vid1->info; if (register_framebuffer(info) < 0) { mem_release(dm.vid1); printk(KERN_ERR VID1_FBNAME "Unable to register VID1 framebuffer\n"); mem_release(dm.vid1); } else { printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node, info->fix.id); dm64xxfb_set_par(info); } } /* install our interrupt service routine */ if (request_irq(IRQ_VENCINT, dm64xxfb_isr, SA_SHIRQ, DRIVER, &dm)) { printk(KERN_ERR DRIVER ": could not install interrupt service routine\n"); goto exit; } /* Turn ON the output device */ dm.output_device_config(1);printk("33333(((((((EER=%x\n",dispc_reg_in(EER));printk("(((((((((((EERH=%x\n",dispc_reg_in(EERH));printk("(((((((((((EECR=%x\n",dispc_reg_in(EECR));printk("(((((((((((EECRH=%x\n",dispc_reg_in(EECRH));printk("(((((((((((EESR=%x\n",dispc_reg_in(EESR));printk("(((((((((((EESRH=%x\n",dispc_reg_in(EESRH)); RETURN(0);exit: dm64xxfb_cleanup(); RETURN(-ENODEV); unmap_mmio: iounmap((void*)dm.mmio_base);release_mmio: release_mem_region(dm.mmio_base_phys, dm.mmio_size); RETURN(-ENODEV);} /* * Cleanup */static void dm64xxfb_cleanup(void){ DBGENTER; free_irq(IRQ_VENCINT, &dm); /* Cleanup all framebuffers */ if (dm.osd0) { unregister_framebuffer(&dm.osd0->info); mem_release(dm.osd0); } if (dm.osd1) { unregister_framebuffer(&dm.osd1->info); mem_release(dm.osd1); } if (dm.vid0) { unregister_framebuffer(&dm.vid0->info); mem_release(dm.vid0); } if (dm.vid1) { unregister_framebuffer(&dm.vid1->info); mem_release(dm.vid1); } /* Turn OFF the output device */ dm.output_device_config(0);#ifdef REVISIT if(dm.mmio_base) iounmap((void*)dm.mmio_base); release_mem_region(dm.mmio_base_phys, dm.mmio_size);#endif DBGEXIT;}/* ------------------------------------------------------------------------- */ /* * Frame buffer operations */static struct fb_ops dm64xxfb_ops = { .owner = THIS_MODULE, .fb_check_var = dm64xxfb_check_var, .fb_set_par = dm64xxfb_set_par, .fb_setcolreg = dm64xxfb_setcolreg, .fb_blank = dm64xxfb_blank, .fb_parect = cfb_fillrect, .fb_con_display = dm64xxfb_pan_display,
.fb_fillpyarea = cfb_copyarea, .fb_imageblit = cfb_imageblit, .fb_cursor = soft_cursor, .fb_rotate = NULL, .fb_sync = NULL, .fb_ioctl = dm64xxfb_ioctl,};/* ------------------------------------------------------------------------- */ /* * Modularization */module_init(dm64xxfb_init);//入口module_exit(dm64xxfb_cleanup);//在module.h中定义的几个宏
MODULE_DESCRIPTION("Framebuffer driver for TI DM644x DV-EVM Board");MODULE_AUTHOR("Texas Instruments");MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -