From: Davide Bonfanti <davide.bonfa...@bticino.it>

Signed-off-by: Davide Bonfanti <davide.bonfa...@bticino.it>
Signed-off-by: Raffaele Recalcati <raffaele.recalc...@bticino.it>
---
 drivers/video/davincifb.c |  134 +++++++++++++++++++++++++++------------------
 include/video/davincifb.h |   65 ++++++++++++++++++++++
 2 files changed, 145 insertions(+), 54 deletions(-)

diff --git a/drivers/video/davincifb.c b/drivers/video/davincifb.c
index 1344be7..dabee4d 100644
--- a/drivers/video/davincifb.c
+++ b/drivers/video/davincifb.c
@@ -78,47 +78,7 @@ static __inline__ u32 dispc_reg_merge(u32 reg, u32 val, u32 
mask)
 /* usage:      if (is_win(info->fix.id, OSD0)) ... */
 #define is_win(name, x) ((strcmp(name, x ## _FBNAME) == 0) ? 1 : 0)
 
-struct dm_win_info {
-       struct fb_info info;
-
-       /* X and Y position */
-       unsigned int x, y;
-
-       /* framebuffer area */
-       dma_addr_t fb_base_phys;
-       unsigned long fb_base;
-       unsigned long fb_size;
-
-       u32 pseudo_palette[17];
-
-       /* flag to identify if framebuffer area is fixed already or not */
-       int alloc_fb_mem;
-       unsigned long sdram_address;
-       struct dm_info *dm;
-};
-
-static struct dm_info {
-       struct dm_win_info *osd0;
-       struct dm_win_info *osd1;
-       struct dm_win_info *vid0;
-       struct dm_win_info *vid1;
-
-       /* to map the registers */
-       dma_addr_t mmio_base_phys;
-       unsigned long mmio_base;
-       unsigned long mmio_size;
-
-       wait_queue_head_t vsync_wait;
-       unsigned long vsync_cnt;
-       int timeout;
-
-       /* this is the function that configures the output device (NTSC/PAL/LCD)
-        * for the required output format (composite/s-video/component/rgb)
-        */
-       void (*output_device_config) (int on);
-
-       struct device *dev;
-} dm_static;
+static struct dm_info dm_static;
 static struct dm_info *dm = &dm_static;
 
 static struct fb_ops davincifb_ops;
@@ -754,7 +714,7 @@ static int davincifb_set_par(struct fb_info *info)
        start = (u32) w->fb_base_phys + offset;
        set_sdram_params(info->fix.id, start, info->fix.line_length);
 
-       set_interlaced(info->fix.id, 1);
+       set_interlaced(info->fix.id, info->var.vmode);
        set_win_position(info->fix.id,
                         x_pos(w), y_pos(w), v->xres, v->yres / 2);
        set_win_mode(info->fix.id);
@@ -1212,6 +1172,7 @@ static struct fb_info *init_fb_info(struct dm_win_info *w,
        info->screen_base = (char *)(w->fb_base);
        info->pseudo_palette = w->pseudo_palette;
        info->par = w;
+       info->screen_size = w->fb_size;
 
        /* Initialize variable screeninfo.
         * The variable screeninfo can be directly specified by the user
@@ -1224,6 +1185,8 @@ static struct fb_info *init_fb_info(struct dm_win_info *w,
         * The fixed screeninfo cannot be directly specified by the user, but
         * it may change to reflect changes to the var info.
         */
+       info->var.xres_virtual = info->var.xres;
+       info->var.yres_virtual = info->var.yres;
        strlcpy(info->fix.id, id, sizeof(info->fix.id));
        info->fix.smem_start = w->fb_base_phys;
        info->fix.line_length =
@@ -1261,6 +1224,9 @@ static void davincifb_ntsc_composite_config(int on)
 
                /* Enable all DACs  */
                dispc_reg_out(VENC_DACTST, 0);
+               /* Set Base Pixel X and Base Pixel Y */
+               dispc_reg_out(OSD_BASEPX, BASEX);
+               dispc_reg_out(OSD_BASEPY, BASEY);
        } else {
                /* Reset video encoder module */
                dispc_reg_out(VENC_VMOD, 0);
@@ -1287,6 +1253,9 @@ static void davincifb_ntsc_svideo_config(int on)
 
                /* Enable all DACs  */
                dispc_reg_out(VENC_DACTST, 0);
+               /* Set Base Pixel X and Base Pixel Y */
+               dispc_reg_out(OSD_BASEPX, BASEX);
+               dispc_reg_out(OSD_BASEPY, BASEY);
        } else {
                /* Reset video encoder module */
                dispc_reg_out(VENC_VMOD, 0);
@@ -1313,6 +1282,9 @@ static void davincifb_ntsc_component_config(int on)
 
                /* Enable all DACs  */
                dispc_reg_out(VENC_DACTST, 0);
+               /* Set Base Pixel X and Base Pixel Y */
+               dispc_reg_out(OSD_BASEPX, BASEX);
+               dispc_reg_out(OSD_BASEPY, BASEY);
        } else {
                /* Reset video encoder module */
                dispc_reg_out(VENC_VMOD, 0);
@@ -1336,6 +1308,9 @@ static void davincifb_pal_composite_config(int on)
 
                /* Enable all DACs  */
                dispc_reg_out(VENC_DACTST, 0);
+               /* Set Base Pixel X and Base Pixel Y */
+               dispc_reg_out(OSD_BASEPX, BASEX);
+               dispc_reg_out(OSD_BASEPY, BASEY);
        } else {
                /* Reset video encoder module */
                dispc_reg_out(VENC_VMOD, 0);
@@ -1362,6 +1337,9 @@ static void davincifb_pal_svideo_config(int on)
 
                /* Enable all DACs  */
                dispc_reg_out(VENC_DACTST, 0);
+               /* Set Base Pixel X and Base Pixel Y */
+               dispc_reg_out(OSD_BASEPX, BASEX);
+               dispc_reg_out(OSD_BASEPY, BASEY);
        } else {
                /* Reset video encoder module */
                dispc_reg_out(VENC_VMOD, 0);
@@ -1388,6 +1366,9 @@ static void davincifb_pal_component_config(int on)
 
                /* Enable all DACs  */
                dispc_reg_out(VENC_DACTST, 0);
+               /* Set Base Pixel X and Base Pixel Y */
+               dispc_reg_out(OSD_BASEPX, BASEX);
+               dispc_reg_out(OSD_BASEPY, BASEY);
        } else {
                /* Reset video encoder module */
                dispc_reg_out(VENC_VMOD, 0);
@@ -1449,6 +1430,7 @@ static int davincifb_remove(struct platform_device *pdev)
 static int davincifb_probe(struct platform_device *pdev)
 {
        struct fb_info *info;
+       struct davincifb_platform_data *pdata;
 
        if (dmparams.windows == 0)
                return 0;       /* user disabled all windows through bootargs */
@@ -1462,6 +1444,7 @@ static int davincifb_probe(struct platform_device *pdev)
                return (-ENODEV);
        }
 
+       pdata = pdev->dev.platform_data;
        /* map the regions */
        dm->mmio_base =
            (unsigned long)ioremap(dm->mmio_base_phys, dm->mmio_size);
@@ -1497,10 +1480,6 @@ static int davincifb_probe(struct platform_device *pdev)
        /* 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);
@@ -1508,9 +1487,6 @@ static int davincifb_probe(struct platform_device *pdev)
        /* 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 "
@@ -1535,13 +1511,59 @@ static int davincifb_probe(struct platform_device *pdev)
 
        /* Setup OSD0 framebuffer */
        if ((dmparams.windows & (1 << OSD0)) &&
-           (!mem_alloc(&dm->osd0, OSD0_FB_PHY, OSD0_FB_SIZE, OSD0_FBNAME))) {
+           (!mem_alloc(&dm->osd0, OSD0_FB_PHY, \
+                       round_32((pdata->xres)*pdata->bits_per_pixel/8) * \
+                       pdata->yres * DOUBLE_BUF, 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 (pdata->xres) {
+                       dmparams.osd0_xres = pdata->xres;
+                       dm->osd0->info.var.xres = pdata->xres;
+                       dm->osd0->info.var.xres_virtual = pdata->xres;
+               }
+               if (pdata->yres) {
+                       dmparams.osd0_yres = pdata->yres;
+                       dm->osd0->info.var.yres = pdata->yres;
+                       dm->osd0->info.var.yres_virtual = \
+                               pdata->yres * DOUBLE_BUF;
+               }
+               if (pdata->xoffset) {
+                       dmparams.osd0_xpos = pdata->xoffset;
+                       dm->osd0->info.var.xoffset = pdata->xoffset;
+               }
+               if (pdata->yoffset) {
+                       dmparams.osd0_ypos = pdata->yoffset;
+                       dm->osd0->info.var.yoffset = pdata->yoffset;
+               }
+               if (pdata->bits_per_pixel)
+                       dm->osd0->info.var.bits_per_pixel = \
+                               pdata->bits_per_pixel;
+               if (pdata->height)
+                       dm->osd0->info.var.height = pdata->height;
+               if (pdata->width) {
+                       dm->osd0->info.var.width = pdata->width;
+                       dm->osd0->info.fix.line_length = pdata->width * \
+                               pdata->bits_per_pixel / 8;
+               }
+               if (pdata->pixclock)
+                       dm->osd0->info.var.pixclock = pdata->pixclock;
+               if (pdata->left_margin)
+                       dm->osd0->info.var.left_margin = pdata->left_margin;
+               if (pdata->right_margin)
+                       dm->osd0->info.var.right_margin = pdata->right_margin;
+               if (pdata->upper_margin)
+                       dm->osd0->info.var.upper_margin = pdata->upper_margin;
+               if (pdata->lower_margin)
+                       dm->osd0->info.var.lower_margin = pdata->lower_margin;
+               if (pdata->hsync_len)
+                       dm->osd0->info.var.hsync_len = pdata->hsync_len;
+               if (pdata->vsync_len)
+                       dm->osd0->info.var.vsync_len = pdata->vsync_len;
+               if (pdata->vmode)
+                       dm->osd0->info.var.vmode = pdata->vmode;
+               dm->osd0->info.var.sync = pdata->sync;
+
                if (davincifb_check_var(&info->var, info)) {
                        dev_err(dm->dev, ": invalid default video mode\n");
                        mem_release(dm->osd0);
@@ -1585,6 +1607,10 @@ static int davincifb_probe(struct platform_device *pdev)
                               dm->vid1->fb_size);
        }
 
+       /* Field Inversion Workaround */
+       if (dm->osd0->info.var.vmode == FB_VMODE_INTERLACED)
+               dispc_reg_out(OSD_MODE, 0x200);
+
        /* Register OSD0 framebuffer */
        if (dm->osd0) {
                info = &dm->osd0->info;
diff --git a/include/video/davincifb.h b/include/video/davincifb.h
index 96b5c20..7e4f216 100644
--- a/include/video/davincifb.h
+++ b/include/video/davincifb.h
@@ -438,5 +438,70 @@ struct zoom_params
        u_int32_t zoom_v;
 };
 #define FBIO_SETZOOM           _IOW('F', 0x24, struct zoom_params)
+
+
+struct davincifb_platform_data {
+       u32 xres;
+       u32 yres;
+       u32 xoffset;
+       u32 yoffset;
+       u32 bits_per_pixel;
+       u32 height;
+       u32 width;
+       u32 pixclock;           /* picoseconds */
+       u32 left_margin;        /* pixclocks */
+       u32 right_margin;       /* pixclocks */
+       u32 upper_margin;       /* line clocks */
+       u32 lower_margin;       /* line clocks */
+       u32 hsync_len;          /* pixclocks */
+       u32 vsync_len;          /* line clocks */
+       u32 vmode;
+       u32 sync;
+       struct davincifb_ops *ops;
+};
+
+struct dm_win_info {
+       struct fb_info info;
+
+       /* X and Y position */
+       unsigned int x, y;
+
+       /* framebuffer area */
+       dma_addr_t fb_base_phys;
+       unsigned long fb_base;
+       unsigned long fb_size;
+
+       u32 pseudo_palette[17];
+
+       /* flag to identify if framebuffer area is fixed already or not */
+       int alloc_fb_mem;
+       unsigned long sdram_address;
+       struct dm_info *dm;
+};
+
+struct dm_info {
+       struct dm_win_info *osd0;
+       struct dm_win_info *osd1;
+       struct dm_win_info *vid0;
+       struct dm_win_info *vid1;
+
+       /* to map the registers */
+       dma_addr_t mmio_base_phys;
+       unsigned long mmio_base;
+       unsigned long mmio_size;
+
+       wait_queue_head_t vsync_wait;
+       unsigned long vsync_cnt;
+       int timeout;
+       /* this is the function that configures the output device (NTSC/PAL/LCD)
+        * for the required output format (composite/s-video/component/rgb)
+        */
+       void (*output_device_config) (int on);
+       struct davincifb_ops *ops;
+
+       struct device *dev;
+       struct davincifb_platform_data *platform_data;
+};
+
 #define FBIO_GETSTD            _IOR('F', 0x25, u_int32_t)
 #endif /* _DAVINCIFB_H_ */
-- 
1.7.0.4

_______________________________________________
Davinci-linux-open-source mailing list
Davinci-linux-open-source@linux.davincidsp.com
http://linux.davincidsp.com/mailman/listinfo/davinci-linux-open-source

Reply via email to