提交 aaf9fa21 编写于 作者: I Ian Armstrong 提交者: Mauro Carvalho Chehab

V4L/DVB (5908): ivtv-fb: cleanups, prevent fw calls in some cases

Signed-off-by: NIan Armstrong <ian@iarmst.co.uk>
Signed-off-by: NHans Verkuil <hverkuil@xs4all.nl>
Signed-off-by: NMauro Carvalho Chehab <mchehab@infradead.org>
上级 84149a0f
...@@ -185,6 +185,9 @@ struct osd_info { ...@@ -185,6 +185,9 @@ struct osd_info {
unsigned long fb_end_aligned_physaddr; unsigned long fb_end_aligned_physaddr;
#endif #endif
/* Current osd mode */
int osd_mode;
/* Store the buffer offset */ /* Store the buffer offset */
int set_osd_coords_x; int set_osd_coords_x;
int set_osd_coords_y; int set_osd_coords_y;
...@@ -350,6 +353,7 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source, ...@@ -350,6 +353,7 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
unsigned long dest_offset, int count) unsigned long dest_offset, int count)
{ {
DEFINE_WAIT(wait); DEFINE_WAIT(wait);
struct osd_info *oi = itv->osd_info;
/* Nothing to do */ /* Nothing to do */
if (count == 0) { if (count == 0) {
...@@ -358,9 +362,9 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source, ...@@ -358,9 +362,9 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
} }
/* Check Total FB Size */ /* Check Total FB Size */
if ((dest_offset + count) > itv->osd_info->video_buffer_size) { if ((dest_offset + count) > oi->video_buffer_size) {
IVTV_FB_WARN("ivtv_fb_prep_frame: Overflowing the framebuffer %ld, only %d available\n", IVTV_FB_WARN("ivtv_fb_prep_frame: Overflowing the framebuffer %ld, only %d available\n",
dest_offset + count, itv->osd_info->video_buffer_size); dest_offset + count, oi->video_buffer_size);
return -E2BIG; return -E2BIG;
} }
...@@ -387,7 +391,7 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source, ...@@ -387,7 +391,7 @@ static int ivtv_fb_prep_frame(struct ivtv *itv, int cmd, void __user *source,
} }
/* OSD Address to send DMA to */ /* OSD Address to send DMA to */
dest_offset += IVTV_DEC_MEM_START + itv->osd_info->video_rbase; dest_offset += IVTV_DEC_MEM_START + oi->video_rbase;
/* Fill Buffers */ /* Fill Buffers */
return ivtv_fb_prep_dec_dma_to_device(itv, dest_offset, source, count); return ivtv_fb_prep_dec_dma_to_device(itv, dest_offset, source, count);
...@@ -445,8 +449,10 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar ...@@ -445,8 +449,10 @@ static int ivtvfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long ar
static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
{ {
struct osd_info *oi = itv->osd_info;
struct ivtv_osd_coords ivtv_osd; struct ivtv_osd_coords ivtv_osd;
struct v4l2_rect ivtv_window; struct v4l2_rect ivtv_window;
int osd_mode = -1;
IVTV_FB_DEBUG_INFO("ivtvfb_set_var\n"); IVTV_FB_DEBUG_INFO("ivtvfb_set_var\n");
...@@ -456,32 +462,24 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) ...@@ -456,32 +462,24 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
else /* RGB */ else /* RGB */
write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00); write_reg(read_reg(0x02a00) & ~0x0002000, 0x02a00);
/* Set the color mode /* Set the color mode */
Although rare, occasionally things go wrong. The extra mode
change seems to help... */
switch (var->bits_per_pixel) { switch (var->bits_per_pixel) {
case 8: case 8:
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); osd_mode = IVTV_OSD_BPP_8;
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_8);
break; break;
case 32: case 32:
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); osd_mode = IVTV_OSD_BPP_32;
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_32);
break; break;
case 16: case 16:
switch (var->green.length) { switch (var->green.length) {
case 4: case 4:
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); osd_mode = IVTV_OSD_BPP_16_444;
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_16_444);
break; break;
case 5: case 5:
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); osd_mode = IVTV_OSD_BPP_16_555;
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_16_555);
break; break;
case 6: case 6:
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0); osd_mode = IVTV_OSD_BPP_16_565;
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, IVTV_OSD_BPP_16_565);
break; break;
default: default:
IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
...@@ -491,8 +489,17 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var) ...@@ -491,8 +489,17 @@ static int ivtvfb_set_var(struct ivtv *itv, struct fb_var_screeninfo *var)
IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n"); IVTV_FB_DEBUG_WARN("ivtvfb_set_var - Invalid bpp\n");
} }
itv->osd_info->bits_per_pixel = var->bits_per_pixel; /* Change osd mode if needed.
itv->osd_info->bytes_per_pixel = var->bits_per_pixel / 8; Although rare, things can go wrong. The extra mode
change seems to help... */
if (osd_mode != -1 && osd_mode != oi->osd_mode) {
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, 0);
ivtv_vapi(itv, CX2341X_OSD_SET_PIXEL_FORMAT, 1, osd_mode);
oi->osd_mode = osd_mode;
}
oi->bits_per_pixel = var->bits_per_pixel;
oi->bytes_per_pixel = var->bits_per_pixel / 8;
/* Set the flicker filter */ /* Set the flicker filter */
switch (var->vmode & FB_VMODE_MASK) { switch (var->vmode & FB_VMODE_MASK) {
...@@ -887,6 +894,9 @@ static int ivtvfb_init_vidmode(struct ivtv *itv) ...@@ -887,6 +894,9 @@ static int ivtvfb_init_vidmode(struct ivtv *itv)
oi->bits_per_pixel = osd_depth; oi->bits_per_pixel = osd_depth;
oi->bytes_per_pixel = oi->bits_per_pixel / 8; oi->bytes_per_pixel = oi->bits_per_pixel / 8;
/* Invalidate current osd mode to force a mode switch later */
oi->osd_mode = -1;
/* Horizontal size & position */ /* Horizontal size & position */
if (osd_xres > 720) osd_xres = 720; if (osd_xres > 720) osd_xres = 720;
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册