@@ -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;
@@ -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_ */