📄 davincifb.c
字号:
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 davincifb_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;
}
/* Logic Product Development
* Ryan Link
* DSP_Team
*/
static void davincifb_lcd_rgb_config(int on)
{
DBGENTER;
if (on) {
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
// set LCD_OE to be active, enable RGB666 mode
dispc_reg_merge(PINMUX0, 0x01400000, 0x01400000);
// turn off REC656 mode
dispc_reg_out(VENC_YCCCTL, 0x0);
set_lcd_timings(default_lcd_timing.h_valid, default_lcd_timing.v_valid,
default_lcd_timing.h_interval, default_lcd_timing.v_interval,
default_lcd_timing.h_pulse, default_lcd_timing.v_pulse,
default_lcd_timing.h_start, default_lcd_timing.v_start,
default_lcd_timing.h_delay, default_lcd_timing.v_delay,
default_lcd_timing.hsync_pol,
default_lcd_timing.vsync_pol,
default_lcd_timing.oe_pol);
// enable LCD_OE set active high
//dispc_reg_out(VENC_LCDOUT, 0x0001);
/* Enable VCLK */
dispc_reg_out(VENC_DCLKCTL, 0x801);
dispc_reg_out(VENC_DCLKPTN0, 0x03);
dispc_reg_out(VENC_DCLKPTN1, 0x0);
dispc_reg_out(VENC_DCLKPTN2, 0x0);
dispc_reg_out(VENC_DCLKPTN3, 0x0);
dispc_reg_out(VENC_DCLKPTN0A, 0x3);
dispc_reg_out(VENC_DCLKPTN1A, 0x0);
dispc_reg_out(VENC_DCLKPTN2A, 0x0);
dispc_reg_out(VENC_DCLKPTN3A, 0x0);
dispc_reg_out(VENC_OSDCLK1, 3);
/* Enable VCLK */
dispc_reg_out(VENC_VIDCTL, 0x2000);
/* Enable RGB mode and enable VENC */
dispc_reg_out(VENC_VMOD, 0x2013);
}
else {
/* Reset video encoder module */
dispc_reg_out(VENC_VMOD, 0);
}
DBGEXIT;
}
static inline void fix_default_var(struct dm_win_info *w,
u32 xres, u32 yres, u32 xpos, u32 ypos,
int n_buf)
{
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;
}
/*
* Cleanup
*/
static int davincifb_remove(struct device *dev)
{
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);
if (dm->mmio_base)
iounmap((void *)dm->mmio_base);
release_mem_region(dm->mmio_base_phys, dm->mmio_size);
DBGEXIT;
return 0;
}
/*
* Initialization
*/
static int davincifb_probe(struct device *dev)
{
struct platform_device *pdev;
struct fb_info *info;
DBGENTER;
pdev = to_platform_device(dev);
if (pdev->num_resources != 0) {
dev_err(dev, "probed for an unknown device\n");
return -ENODEV;
}
if (dmparams.windows == 0)
return 0; /* user disabled all windows through bootargs */
dm->dev = dev;
dm->mmio_base_phys = OSD_REG_BASE;
dm->mmio_size = OSD_REG_SIZE;
if (!request_mem_region
(dm->mmio_base_phys, dm->mmio_size, DAVINCIFB_DRIVER)) {
dev_err(dev, ": 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) {
dev_err(dev, ": cannot map MMIO\n");
goto release_mmio;
}
/* 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 = davincifb_ntsc_composite_config;
else if ((dmparams.output == NTSC) && (dmparams.format == SVIDEO))
dm->output_device_config = davincifb_ntsc_svideo_config;
else if ((dmparams.output == NTSC) && (dmparams.format == COMPONENT))
dm->output_device_config = davincifb_ntsc_component_config;
else if ((dmparams.output == PAL) && (dmparams.format == COMPOSITE))
dm->output_device_config = davincifb_pal_composite_config;
else if ((dmparams.output == PAL) && (dmparams.format == SVIDEO))
dm->output_device_config = davincifb_pal_svideo_config;
else if ((dmparams.output == PAL) && (dmparams.format == COMPONENT))
dm->output_device_config = davincifb_pal_component_config;
// Logic Product Development - Ryan Link - DSP_Team
else if ((dmparams.output == LCD) && (dmparams.format == RGB))
dm->output_device_config = davincifb_lcd_rgb_config;
/* Add support for other displays here */
else {
printk(KERN_WARNING "Unsupported output device!\n");
dm->output_device_config = NULL;
}
printk("Setting Up Clocks for DM420 OSD\n");
/* Initialize the VPSS Clock Control register */
dispc_reg_out(VPSS_CLKCTL, 0x18);
/* 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);
/* Set blue background color */
set_bg_color(0, 162);
/* Field Inversion Workaround */
dispc_reg_out(OSD_MODE, 0x200);
/* Setup VID0 framebuffer */
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 (davincifb_check_var(&info->var, info)) {
dev_err(dev, ": invalid default video mode\n");
goto exit;
}
memset((void *)dm->vid0->fb_base, 0x88, dm->vid0->fb_size);
} else
goto exit;
/* Setup OSD0 framebuffer */
if ((dmparams.windows & (1 << OSD0)) &&
(!mem_alloc(&dm->osd0, OSD0_FB_PHY, OSD0_FB_SIZE, OSD0_FBNAME))) {
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 (davincifb_check_var(&info->var, info)) {
dev_err(dev, ": invalid default video mode\n");
mem_release(dm->osd0);
} else
memset((void *)dm->osd0->fb_base, 0, dm->osd0->fb_size);
}
/* 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 (davincifb_check_var(&info->var, info)) {
dev_err(dev, ": 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);
}
/* 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 (davincifb_check_var(&info->var, info)) {
dev_err(dev,
VID1_FBNAME ": invalid default video mode\n");
mem_release(dm->vid1);
} else
memset((void *)dm->vid1->fb_base, 0x88,
dm->vid1->fb_size);
}
/* Register OSD0 framebuffer */
if (dm->osd0) {
info = &dm->osd0->info;
if (register_framebuffer(info) < 0) {
dev_err(dev, 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);
davincifb_set_par(info);
}
}
/* Register VID0 framebuffer */
info = &dm->vid0->info;
if (register_framebuffer(info) < 0) {
dev_err(dev,
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);
davincifb_set_par(info);
}
/* Register OSD1 framebuffer */
if (dm->osd1) {
info = &dm->osd1->info;
if (register_framebuffer(info) < 0) {
dev_err(dev, 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);
davincifb_set_par(info);
}
}
/* Register VID1 framebuffer */
if (dm->vid1) {
info = &dm->vid1->info;
if (register_framebuffer(info) < 0) {
mem_release(dm->vid1);
dev_err(dev, 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);
davincifb_set_par(info);
}
}
/* install our interrupt service routine */
if (request_irq(IRQ_VENCINT, davincifb_isr, SA_SHIRQ, DAVINCIFB_DRIVER,
dm)) {
dev_err(dev, DAVINCIFB_DRIVER
": could not install interrupt service routine\n");
goto exit;
}
/* Turn ON the output device */
dm->output_device_config(1);
RETURN(0);
exit:
davincifb_remove(dev);
RETURN(-ENODEV);
unmap_mmio:
iounmap((void *)dm->mmio_base);
release_mmio:
release_mem_region(dm->mmio_base_phys, dm->mmio_size);
RETURN(-ENODEV);
}
/* ------------------------------------------------------------------------- */
/*
* Frame buffer operations
*/
static struct fb_ops davincifb_ops = {
.owner = THIS_MODULE,
.fb_check_var = davincifb_check_var,
.fb_set_par = davincifb_set_par,
.fb_setcolreg = davincifb_setcolreg,
.fb_blank = davincifb_blank,
.fb_pan_display = davincifb_pan_display,
.fb_fillrect = cfb_fillrect,
.fb_copyarea = cfb_copyarea,
.fb_imageblit = cfb_imageblit,
.fb_cursor = soft_cursor,
.fb_rotate = NULL,
.fb_sync = NULL,
.fb_ioctl = davincifb_ioctl,
};
static void davincifb_release_dev(struct device *dev)
{
}
static u64 davincifb_dmamask = ~(u32) 0;
static struct platform_device davincifb_device = {
.name = DAVINCIFB_DEVICE,
.id = 0,
.dev = {
.release = davincifb_release_dev,
.dma_mask = &davincifb_dmamask,
.coherent_dma_mask = 0xffffffff,
},
.num_resources = 0,
};
static struct device_driver davincifb_driver = {
.name = DAVINCIFB_DRIVER,
.bus = &platform_bus_type,
.probe = davincifb_probe,
.remove = davincifb_remove,
.suspend = NULL,
.resume = NULL,
};
/* Register both the driver and the device */
int __init davincifb_init(void)
{
int r = 0;
struct device *dev = &davincifb_device.dev;
DBGENTER;
#ifndef MODULE
{
/* handle options for "dm64xxfb" for backwards compatability */
char *option;
char *names[] = { "davincifb", "dm64xxfb" };
int i, num_names = 2, done = 0;
for (i = 0; i < num_names && !done; i++) {
if (fb_get_options(names[i], &option)) {
printk(DAVINCIFB_DRIVER
": Disabled on command-line.\n");
r = -ENODEV;
goto exit;
} else if (option) {
davincifb_setup(option);
done = 1;
}
}
}
#endif
/* Register the device with LDM */
if (platform_device_register(&davincifb_device)) {
dev_err(dev, "failed to register davincifb device\n");
r = -ENODEV;
goto exit;
}
/* Register the driver with LDM */
if (driver_register(&davincifb_driver)) {
dev_err(dev, "failed to register davincifb driver\n");
platform_device_unregister(&davincifb_device);
r = -ENODEV;
goto exit;
}
exit:
DBGEXIT;
return r;
}
static void __exit davincifb_cleanup(void)
{
DBGENTER;
driver_unregister(&davincifb_driver);
platform_device_unregister(&davincifb_device);
DBGEXIT;
}
module_init(davincifb_init);
module_exit(davincifb_cleanup);
MODULE_DESCRIPTION("Framebuffer driver for TI DaVinci");
MODULE_AUTHOR("Texas Instruments");
MODULE_LICENSE("GPL");
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -