📄 davincifb.c
字号:
(dmparams.format == 0) ? "" : (dmparams.format == COMPOSITE) ? " in COMPOSITE format": (dmparams.format == SVIDEO) ? " in SVIDEO format": (dmparams.format == COMPONENT) ? " in COMPONENT format": (dmparams.format == RGB) ? " in RGB format" : "", (dmparams.windows & (1 << VID0)) ? "Video0" : "", (dmparams.windows & (1 << VID1)) ? "Video1" : "", (dmparams.windows & (1 << OSD0)) ? "OSD0" : "", (dmparams.windows & (1 << OSD1)) ? "OSD1" : ""); if (dmparams.output == NTSC) { format_yres = 480; } else if (dmparams.output == PAL) { format_yres = 576; } else { printk(KERN_INFO "DM64XX:invalid format..defaulting width to 480\n"); } dmparams.osd0_yres = osd0_default_var.yres = format_yres;
dmparams.osd1_yres = osd1_default_var.yres = format_yres; dmparams.vid0_yres = vid0_default_var.yres = format_yres; dmparams.vid1_yres = vid1_default_var.yres = format_yres; osd0_default_var.yres_virtual = format_yres * DOUBLE_BUF; osd1_default_var.yres_virtual = format_yres * DOUBLE_BUF; vid0_default_var.yres_virtual = format_yres * TRIPLE_BUF; vid1_default_var.yres_virtual = format_yres * TRIPLE_BUF; if (dmparams.windows & (1 << VID0)) printk(KERN_INFO "Setting Video0 size %dx%d, " "position (%d,%d)\n", dmparams.vid0_xres, dmparams.vid0_yres, dmparams.vid0_xpos, dmparams.vid0_ypos); if (dmparams.windows & (1 << VID1)) printk(KERN_INFO "Setting Video1 size %dx%d, " "position (%d,%d)\n", dmparams.vid1_xres, dmparams.vid1_yres, dmparams.vid1_xpos, dmparams.vid1_ypos); if (dmparams.windows & (1 << OSD0)) printk(KERN_INFO "Setting OSD0 size %dx%d, " "position (%d,%d)\n", dmparams.osd0_xres, dmparams.osd0_yres, dmparams.osd0_xpos, dmparams.osd0_ypos);
if (dmparams.windows & (1 << OSD1))
printk(KERN_INFO "Setting OSD1 size %dx%d, "
"position (%d,%d)\n",
dmparams.osd1_xres, dmparams.osd1_yres,
dmparams.osd1_xpos, dmparams.osd1_ypos); RETURN(0);}__setup("video",dm64xxfb_setup);#endifstatic int mem_release(struct dm_win_info *w) //释放指定窗口的ram空间{ DBGENTER; if (!w->alloc_fb_mem) { iounmap((void*)w->fb_base); release_mem_region(w->fb_base_phys, w->fb_size); } else dma_free_coherent(NULL, w->fb_size, (void *)w->fb_base, w->fb_base_phys); kfree(w); RETURN(0);}static int mem_alloc(struct dm_win_info **win, dma_addr_t fb_base_phys, unsigned long fb_size, char *fbname) { struct dm_win_info *w; DBGENTER; w = kmalloc(sizeof(struct dm_win_info), GFP_KERNEL);//申请空间 if (!w) { printk(KERN_ERR "%s: could not allocate memory\n", fbname); RETURN(-ENOMEM); } memset(w, 0, sizeof(struct dm_win_info)); //初始化内存,初始化为0 w->fb_base_phys = fb_base_phys; //初始化为给定的起始地址和大小 w->fb_size = fb_size; /* A null base address indicates that the framebuffer memory should be * dynamically allocated. */ if (!w->fb_base_phys) //若给了一个值为0(NULL)的地址,则FB memory要动态的分配 w->alloc_fb_mem = 1; if (!w->alloc_fb_mem) { if (!request_mem_region(w->fb_base_phys, w->fb_size, fbname)) // 请求内存 { printk(KERN_ERR "%s: cannot reserve FB region\n", fbname); goto free_par; } w->fb_base = (unsigned long) ioremap(w->fb_base_phys, w->fb_size); //空间映射 if (!w->fb_base) { printk(KERN_ERR "%s: cannot map framebuffer\n", fbname); goto release_fb; } } else { /* allocate coherent memory for the framebuffer */ w->fb_base = (unsigned long) dma_alloc_coherent(NULL,
w->fb_size, &w->fb_base_phys, GFP_KERNEL | GFP_DMA);
if (!w->fb_base) {
printk(KERN_ERR "%s: cannot allocate "
"framebuffer\n", fbname);
goto free_par;
}
// printk("Framebuffer allocated at 0x%lx, mapped to 0x%p, size %dk\n",
// w->fb_base_phys, w->fb_base, w->fb_size/1024);
} *win = w; RETURN(0);release_fb: if (!w->alloc_fb_mem) release_mem_region(w->fb_base_phys, w->fb_size);free_par: kfree(w); RETURN(-ENOMEM);}static struct fb_info *init_fb_info(struct dm_win_info *w, struct fb_var_screeninfo *var, char *id) //指针函数,初始化fb_info{ struct fb_info *info = &(w->info); struct dm_info *dm = w->dm; DBGENTER;// printk("Entered the Davinci FB Init Routine\n"); /* initialize the fb_info structure */ info->flags = FBINFO_DEFAULT; info->fbops = &dm64xxfb_ops; info->screen_base = (char *)(w->fb_base);/* info->currcon = -1; */ info->pseudo_palette = w->pseudo_palette; info->par = w; /* Initialize variable screeninfo. * The variable screeninfo can be directly specified by the user * via an ioctl. */ memcpy(&info->var, var, sizeof(info->var)); info->var.activate = FB_ACTIVATE_NOW; /* Initialize fixed screeninfo. * The fixed screeninfo cannot be directly specified by the user, but * it may change to reflect changes to the var info. */ strlcpy(info->fix.id, id, sizeof(info->fix.id)); info->fix.smem_start = w->fb_base_phys; info->fix.line_length = (info->var.xres_virtual*info->var.bits_per_pixel)/8; info->fix.smem_len = w->fb_size; info->fix.type = FB_TYPE_PACKED_PIXELS; info->fix.visual = (info->var.bits_per_pixel <= 8) ? FB_VISUAL_PSEUDOCOLOR: FB_VISUAL_TRUECOLOR; info->fix.xpanstep = 0; info->fix.ypanstep = 0; info->fix.ywrapstep = 0; info->fix.type_aux = 0; info->fix.mmio_start = dm->mmio_base_phys; info->fix.mmio_len = dm->mmio_size; info->fix.accel = FB_ACCEL_NONE; if(dmparams.output==LCDS) { info->fix.type_aux=1; printk(" ====into LCD and set no interlaced\n"); } DBGEXIT; return info;}static void dm64xxfb_ntsc_composite_config(int on){ DBGENTER; if (on) { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); //寄存器的设置方法,可以照着写其他的 /* Enable Composite output and start video encoder */ dispc_reg_out(VENC_VMOD, (VENC_VMOD_VIE | VENC_VMOD_VENC)); /* Set REC656 Mode */ dispc_reg_out(VENC_YCCCTL, 0x1); /* Enable output mode and NTSC */ dispc_reg_out(VENC_VMOD, 0x1003); /* Enable all DACs */ dispc_reg_out(VENC_DACTST, 0); } else { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); } DBGEXIT;}static void dm64xxfb_ntsc_svideo_config(int on){ DBGENTER; if (on) { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); /* Enable Composite output and start video encoder */ dispc_reg_out(VENC_VMOD, (VENC_VMOD_VIE | VENC_VMOD_VENC)); /* Set REC656 Mode */ dispc_reg_out(VENC_YCCCTL, 0x1); /* Enable output mode and NTSC */ dispc_reg_out(VENC_VMOD, 0x1003); /* Enable S-Video Output; DAC B: S-Video Y, DAC C: S-Video C */ dispc_reg_out(VENC_DACSEL, 0x210); /* Enable all DACs */ dispc_reg_out(VENC_DACTST, 0); } else { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); } DBGEXIT;}static void dm64xxfb_ntsc_component_config(int on){ DBGENTER; if (on) { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); /* Enable Composite output and start video encoder */ dispc_reg_out(VENC_VMOD, (VENC_VMOD_VIE | VENC_VMOD_VENC)); /* Set REC656 Mode */ dispc_reg_out(VENC_YCCCTL, 0x1); /* Enable output mode and NTSC */ dispc_reg_out(VENC_VMOD, 0x1003); /* Enable Component output; DAC A: Y, DAC B: Pb, DAC C: Pr */ dispc_reg_out(VENC_DACSEL, 0x543); /* Enable all DACs */ dispc_reg_out(VENC_DACTST, 0); } else { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); } DBGEXIT;}static void dm64xxfb_pal_composite_config(int on){ DBGENTER; if (on) { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); /* Enable Composite output and start video encoder */ dispc_reg_out(VENC_VMOD, (VENC_VMOD_VIE | VENC_VMOD_VENC)); /* Set REC656 Mode */ dispc_reg_out(VENC_YCCCTL, 0x1); /* Enable output mode and PAL */ dispc_reg_out(VENC_VMOD, 0x1043); /* Enable all DACs */ dispc_reg_out(VENC_DACTST, 0); } else { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); } DBGEXIT;}static void dm64xxfb_pal_svideo_config(int on){ DBGENTER; if (on) { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); /* Enable Composite output and start video encoder */ dispc_reg_out(VENC_VMOD, (VENC_VMOD_VIE | VENC_VMOD_VENC)); /* Set REC656 Mode */ dispc_reg_out(VENC_YCCCTL, 0x1); /* Enable output mode and PAL */ dispc_reg_out(VENC_VMOD, 0x1043); /* Enable S-Video Output; DAC B: S-Video Y, DAC C: S-Video C */ dispc_reg_out(VENC_DACSEL, 0x210); /* Enable all DACs */ dispc_reg_out(VENC_DACTST, 0); } else { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); } DBGEXIT;}static void dm64xxfb_pal_component_config(int on){ DBGENTER; if (on) { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); /* Enable Composite output and start video encoder */ dispc_reg_out(VENC_VMOD, (VENC_VMOD_VIE | VENC_VMOD_VENC)); /* Set REC656 Mode */ dispc_reg_out(VENC_YCCCTL, 0x1); /* Enable output mode and PAL */ dispc_reg_out(VENC_VMOD, 0x1043); /* Enable Component output; DAC A: Y, DAC B: Pb, DAC C: Pr */ dispc_reg_out(VENC_DACSEL, 0x543); /* Enable all DACs */ dispc_reg_out(VENC_DACTST, 0); } else { /* Reset video encoder module */ dispc_reg_out(VENC_VMOD, 0); } DBGEXIT;}
static void dm64xxfb_lcd_config(int on) //配置Lcd输出模式为RGB888
{
if(on)
{ /////////////////////////////// Reset video encoder module dispc_reg_out(VENC_VMOD, 0); //寄存器的设置方法,可以照着写其他的 // Enable Composite output and start video encoder dispc_reg_out(VENC_VMOD, (VENC_VMOD_VIE | VENC_VMOD_VENC)); // Set REC656 Mode dispc_reg_out(VENC_YCCCTL, 0x0); // Enable output mode and NTSC //dispc_reg_out(VENC_VMOD, 0x1003); // Enable all DACs dispc_reg_out(VENC_DACTST, 0xf000);//set 0 to display on small screen,f000, disenablr DAC/////////////////////////////////////// /*使能VPBE的时钟,PCR.CLK_OFF=0 */
dispc_reg_out(VPBE_PCR, 0);
/*设置RGB输出时的数字滤波器频率、以及阶数*/
dispc_reg_out(VENC_RGBCTL,0x8400);
/*设置RGBCLP寄存器 */
dispc_reg_out(VENC_RGBCLP,0xff00);
//读入一个YCC=>RGB转化的矩阵系数,值应该是1404(十进制)
printk("===================\nDRGBX1= %d\n",(inl(VENC_ARGBX1)&0xffff));
/*reset VENC*/
dispc_reg_out(VENC_VMOD, 0);
/* RGB888的引脚复用*//*
PINMUX0|=(1<<23); //在PINMUX0中设置RGB888
PINMUX0&=~(1<<25);
PINMUX0&=~(1<<27);
PINMUX0|=(1<<24); //选通LCD_OE
PINMUX1&=~(1<<5); //设置PINMUX1中的PWM1 为RGB888的输出
PINMUX1&=~(1<<6); //设置PINMUX1中的PWM2 为RGB888的输出*/ dispc_reg_merge(PINMUX0,0xffffffff,1<<23); dispc_reg_merge(PINMUX0,0x0,1<<25); dispc_reg_merge(PINMUX0,0,1<<27); dispc_reg_merge(PINMUX0,0xffffffff,1<<24); dispc_reg_merge(PINMUX1,0,1<<5); dispc_reg_merge(PINMUX1,0,1<<6);
/*使能VENC的时钟,关闭DAC的时钟,VENC的时钟是27M */
// dispc_reg_out(VPSS_CLKCTL, 0x08);
/*使能VENC */
dispc_reg_out(VENC_VMOD, 0x1); dispc_reg_out(VENC_HSTART,0x25);
dispc_reg_out(VENC_HVALID,DISP_XRES); dispc_reg_out(VENC_VVALID,DISP_YRES);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -