diff mbox

[2/4] davinci: Update window size after enabling OSD zoom/expansion.

Message ID 1274187385-10969-2-git-send-email-gilles.chanteperdrix@nexvision.fr (mailing list archive)
State Not Applicable
Headers show

Commit Message

Gilles Chanteperdrix May 18, 2010, 12:56 p.m. UTC
None
diff mbox

Patch

diff --git a/drivers/media/video/davinci/davinci_display.c b/drivers/media/video/davinci/davinci_display.c
index 4c4efef..0ab682c 100644
--- a/drivers/media/video/davinci/davinci_display.c
+++ b/drivers/media/video/davinci/davinci_display.c
@@ -280,7 +280,7 @@  static void davinci_display_isr(unsigned int event, void *dispObj)
 			list_del(&layer->nextFrm->queue);
 			/* Mark status of the buffer as active */
 			layer->nextFrm->state = VIDEOBUF_ACTIVE;
-			
+
 			addr = videobuf_to_dma_contig(layer->nextFrm);
 			davinci_disp_start_layer(layer->layer_info.id,
 						 addr,
@@ -712,7 +712,7 @@  static int vpbe_querycap(struct file *file, void  *priv,
 
 	dev_dbg(davinci_display_dev, "VIDIOC_QUERYCAP, layer id = %d\n",
 			layer->device_id);
-	
+
 	memset(cap, 0, sizeof(*cap));
 	*cap = davinci_display_videocap;
 
@@ -750,7 +750,7 @@  static int vpbe_s_crop(struct file *file, void *priv,
 		ret = mutex_lock_interruptible(&davinci_dm.lock);
 		if (ret)
 			return ret;
-				
+
 		davinci_disp_get_layer_config(layer->layer_info.id,
 						&layer->layer_info.config);
 
@@ -761,7 +761,7 @@  static int vpbe_s_crop(struct file *file, void *priv,
 
 		if (davinci_disp_set_layer_config(layer->layer_info.id,
 			&layer->layer_info.config)) {
-		
+
 			dev_err(davinci_display_dev,
 					"Error in S_CROP params\n");
 			mutex_unlock(&davinci_dm.lock);
@@ -789,7 +789,7 @@  static int vpbe_s_crop(struct file *file, void *priv,
 		dev_err(davinci_display_dev, "Invalid buf type \n");
 		return -EINVAL;
 	}
-	
+
 	return ret;
 }
 
@@ -799,7 +799,7 @@  static int vpbe_g_crop(struct file *file, void *priv,
 	int ret = 0;
 	struct davinci_fh *fh = file->private_data;
 	struct display_obj *layer = fh->layer;
-	
+
 	dev_dbg(davinci_display_dev, "VIDIOC_G_CROP, layer id = %d\n",
 			layer->device_id);
 
@@ -808,7 +808,7 @@  static int vpbe_g_crop(struct file *file, void *priv,
 		ret = mutex_lock_interruptible(&davinci_dm.lock);
 		if (ret)
 			return ret;
-				
+
 		davinci_disp_get_layer_config(layer->layer_info.id,
 						&layer->layer_info.config);
 		rect->top = layer->layer_info.config.ypos;
@@ -820,7 +820,7 @@  static int vpbe_g_crop(struct file *file, void *priv,
 		dev_err(davinci_display_dev,"Invalid buf type \n");
 		ret = -EINVAL;
 	}
-	
+
 	return ret;
 }
 
@@ -830,18 +830,18 @@  static int vpbe_cropcap(struct file *file, void *priv,
 	int ret = 0;
 
 	dev_dbg(davinci_display_dev, "\nStart of VIDIOC_CROPCAP ioctl");
-			
+
 	if (davinci_enc_get_mode(0, &davinci_dm.mode_info)) {
 		dev_err(davinci_display_dev,
 			"Error in getting current display mode"
 			" from enc mngr\n");
 		return -EINVAL;
 	}
-			
+
 	ret = mutex_lock_interruptible(&davinci_dm.lock);
 	if (ret)
 		return ret;
-			
+
 	cropcap->type = V4L2_BUF_TYPE_VIDEO_OUTPUT;
 	if (!strcmp(davinci_dm.mode_info.name, VID_ENC_STD_NTSC)) {
 		cropcap->bounds = cropcap->defrect = ntsc_bounds;
@@ -870,7 +870,7 @@  static int vpbe_cropcap(struct file *file, void *priv,
 		dev_err(davinci_display_dev, "Unknown encoder display mode\n");
 		return -EINVAL;
 	}
-	
+
 	mutex_unlock(&davinci_dm.lock);
 	dev_dbg(davinci_display_dev, "\nEnd of VIDIOC_CROPCAP ioctl");
 
@@ -891,14 +891,14 @@  static int vpbe_streamoff(struct file *file, void *priv,
 		dev_err(davinci_display_dev, "No io_allowed\n");
 		return -EACCES;
 	}
-			
+
 	/* If streaming is not started, return error */
 	if (!layer->started) {
 		dev_err(davinci_display_dev, "streaming not started in layer"
 			" id = %d\n", layer->device_id);
 		return -EINVAL;
 	}
-			
+
 	ret = mutex_lock_interruptible(&davinci_dm.lock);
 	if (ret)
 		return ret;
@@ -973,7 +973,7 @@  static int vpbe_streamon(struct file *file, void *priv,
 	layer->started = 1;
 	dev_dbg(davinci_display_dev, "Started streaming on layer id = %d,"
 		" ret = %d\n", layer->device_id, ret);
-			
+
 	layer_first_int = 1;
 	mutex_unlock(&davinci_dm.lock);
 
@@ -1059,7 +1059,7 @@  static int vpbe_reqbufs(struct file *file, void *priv,
 	if (ret)
 		return ret;
 	/* Initialize videobuf queue as per the buffer type */
-			
+
 	videobuf_queue_dma_contig_init(&layer->buffer_queue,
 					    &video_qops, davinci_display_dev,
 					    &layer->irqlock,
@@ -1131,7 +1131,7 @@  static int vpbe_s_fmt(struct file *file, void *priv,
 			return -EBUSY;
 		}
 	}
-				
+
 	/* store the pixel format in the layer object */
 	davinci_disp_get_layer_config(layer->layer_info.id,
 		&layer->layer_info.config);
@@ -1162,7 +1162,7 @@  static int vpbe_s_fmt(struct file *file, void *priv,
 	/* readback and fill the local copy of current pix format */
 	davinci_disp_get_layer_config(layer->layer_info.id,
 					&layer->layer_info.config);
-		
+
 	/* verify if readback values are as expected */
 	if (layer->pix_fmt.width != layer->layer_info.config.xsize ||
 		layer->pix_fmt.height != layer->layer_info.config.ysize ||
diff --git a/drivers/media/video/davinci/davinci_osd.c b/drivers/media/video/davinci/davinci_osd.c
index 2c498ad..c285f99 100644
--- a/drivers/media/video/davinci/davinci_osd.c
+++ b/drivers/media/video/davinci/davinci_osd.c
@@ -146,7 +146,7 @@  u32 osd_read_upper_margin(void)
 	return __raw_readl(osd->osd_base + OSD_BASEPY);
 }
 EXPORT_SYMBOL(osd_read_upper_margin);
-	
+
 
 /* define some macros for layer and pixfmt classification */
 #define is_osd_win(layer) (((layer) == WIN_OSD0) || ((layer) == WIN_OSD1))
@@ -546,6 +546,127 @@  void davinci_disp_get_vid_expansion(enum davinci_h_exp_ratio *h_exp,
 }
 EXPORT_SYMBOL(davinci_disp_get_vid_expansion);
 
+void davinci_disp_set_vid_size(enum davinci_disp_layer layer,
+	 const struct davinci_layer_config *lconfig)
+{
+	struct davinci_window_state *win = &osd->win[layer];
+	unsigned xsize, ysize;
+
+	xsize = lconfig->xsize << win->h_zoom;
+	ysize = lconfig->ysize << win->v_zoom;
+	switch (osd->osd_h_exp) {
+	case H_EXP_OFF:
+		break;
+	case H_EXP_9_OVER_8:
+		xsize = xsize * 9 / 8;
+		break;
+	case H_EXP_3_OVER_2:
+		xsize = xsize * 3 / 2;
+		break;
+	}
+
+	switch (osd->osd_v_exp) {
+	case V_EXP_OFF:
+		break;
+	case V_EXP_6_OVER_5:
+		ysize = ysize * 6 / 5;
+		break;
+	}
+
+	switch(layer) {
+	case WIN_OSD0:
+		osd_write(lconfig->xpos, OSD_OSDWIN0XP);
+		osd_write(xsize, OSD_OSDWIN0XL);
+		if (lconfig->interlaced) {
+			osd_write(lconfig->ypos >> 1, OSD_OSDWIN0YP);
+			osd_write(ysize >> 1, OSD_OSDWIN0YL);
+		} else {
+			osd_write(lconfig->ypos, OSD_OSDWIN0YP);
+			osd_write(ysize, OSD_OSDWIN0YL);
+		}
+		break;
+
+	case WIN_VID0:
+		osd_write(lconfig->xpos, OSD_VIDWIN0XP);
+		osd_write(xsize, OSD_VIDWIN0XL);
+		if (cpu_is_davinci_dm365()) {
+			if (lconfig->pixfmt == PIXFMT_NV12) {
+				osd_write(lconfig->xpos, OSD_VIDWIN1XP);
+				osd_write(xsize, OSD_VIDWIN1XL);
+				/* if NV21 pixfmt and line length not 32B
+				 * aligned (e.g. NTSC), Need to set window
+				 * X pixel size to be 32B aligned as well
+				 */
+				if (lconfig->xsize % 32) {
+					osd_write(((xsize + 31) & ~31),
+						  OSD_VIDWIN1XL);
+					osd_write(((xsize + 31) & ~31),
+						  OSD_VIDWIN0XL);
+				}
+			}
+		}
+		if (lconfig->interlaced) {
+			osd_write(lconfig->ypos >> 1, OSD_VIDWIN0YP);
+			osd_write(ysize >> 1, OSD_VIDWIN0YL);
+			if (cpu_is_davinci_dm365()
+			    && lconfig->pixfmt == PIXFMT_NV12) {
+				osd_write(lconfig->ypos >> 1, OSD_VIDWIN1YP);
+				osd_write(ysize >> 1, OSD_VIDWIN1YL);
+			}
+		} else {
+			osd_write(lconfig->ypos, OSD_VIDWIN0YP);
+			osd_write(ysize, OSD_VIDWIN0YL);
+			if (cpu_is_davinci_dm365()
+			    && lconfig->pixfmt == PIXFMT_NV12) {
+				osd_write(lconfig->ypos, OSD_VIDWIN1YP);
+				osd_write(ysize, OSD_VIDWIN1YL);
+			}
+		}
+		break;
+
+	case WIN_OSD1:
+		osd_write(lconfig->xpos, OSD_OSDWIN1XP);
+		osd_write(xsize, OSD_OSDWIN1XL);
+		if (lconfig->interlaced) {
+			osd_write(lconfig->ypos >> 1, OSD_OSDWIN1YP);
+			osd_write(ysize >> 1, OSD_OSDWIN1YL);
+		} else {
+			osd_write(lconfig->ypos, OSD_OSDWIN1YP);
+			osd_write(ysize, OSD_OSDWIN1YL);
+		}
+		break;
+
+	case WIN_VID1:
+		osd_write(lconfig->xpos, OSD_VIDWIN1XP);
+		osd_write(lconfig->xsize, OSD_VIDWIN1XL);
+		if (cpu_is_davinci_dm365()) {
+			if (lconfig->pixfmt == PIXFMT_NV12) {
+				osd_write(lconfig->xpos, OSD_VIDWIN0XP);
+				osd_write(lconfig->xsize, OSD_VIDWIN0XL);
+			}
+		}
+
+		if (lconfig->interlaced) {
+			osd_write(lconfig->ypos >> 1, OSD_VIDWIN1YP);
+			osd_write(ysize >> 1, OSD_VIDWIN1YL);
+			if (cpu_is_davinci_dm365()
+			    && lconfig->pixfmt == PIXFMT_NV12) {
+				osd_write(lconfig->ypos >> 1, OSD_VIDWIN0YP);
+				osd_write(ysize >> 1, OSD_VIDWIN0YL);
+			}
+		} else {
+			osd_write(lconfig->ypos, OSD_VIDWIN1YP);
+			osd_write(ysize, OSD_VIDWIN1YL);
+			if (cpu_is_davinci_dm365()
+			    && lconfig->pixfmt == PIXFMT_NV12) {
+				osd_write(lconfig->ypos, OSD_VIDWIN0YP);
+				osd_write(ysize, OSD_VIDWIN0YL);
+			}
+		}
+		break;
+	}
+}
+
 static void _davinci_disp_set_vid_expansion(enum davinci_h_exp_ratio h_exp,
 					    enum davinci_v_exp_ratio v_exp)
 {
@@ -649,6 +770,9 @@  int davinci_disp_set_osd_expansion(enum davinci_h_exp_ratio h_exp,
 
 	osd->osd_h_exp = h_exp;
 	osd->osd_v_exp = v_exp;
+	davinci_disp_set_vid_size(WIN_OSD0, &(osd->win[WIN_OSD0].lconfig));
+	davinci_disp_set_vid_size(WIN_OSD1, &(osd->win[WIN_OSD1].lconfig));
+
 	_davinci_disp_set_osd_expansion(h_exp, v_exp);
 
 	spin_unlock_irqrestore(&osd->lock, flags);
@@ -1289,6 +1413,8 @@  void davinci_disp_set_zoom(enum davinci_disp_layer layer,
 
 	win->h_zoom = h_zoom;
 	win->v_zoom = v_zoom;
+	davinci_disp_set_vid_size(layer, &win->lconfig);
+
 	_davinci_disp_set_zoom(layer, h_zoom, v_zoom);
 
 	spin_unlock_irqrestore(&osd->lock, flags);
@@ -1856,15 +1982,6 @@  static void _davinci_disp_set_layer_config(enum davinci_disp_layer layer,
 
 		osd_merge(winmd_mask, winmd, OSD_OSDWIN0MD);
 		osd_write(lconfig->line_length >> 5, OSD_OSDWIN0OFST);
-		osd_write(lconfig->xpos, OSD_OSDWIN0XP);
-		osd_write(lconfig->xsize, OSD_OSDWIN0XL);
-		if (lconfig->interlaced) {
-			osd_write(lconfig->ypos >> 1, OSD_OSDWIN0YP);
-			osd_write(lconfig->ysize >> 1, OSD_OSDWIN0YL);
-		} else {
-			osd_write(lconfig->ypos, OSD_OSDWIN0YP);
-			osd_write(lconfig->ysize, OSD_OSDWIN0YL);
-		}
 		break;
 	case WIN_VID0:
 		winmd_mask |= OSD_VIDWINMD_VFF0;
@@ -1873,8 +1990,6 @@  static void _davinci_disp_set_layer_config(enum davinci_disp_layer layer,
 
 		osd_merge(winmd_mask, winmd, OSD_VIDWINMD);
 		osd_write(lconfig->line_length >> 5, OSD_VIDWIN0OFST);
-		osd_write(lconfig->xpos, OSD_VIDWIN0XP);
-		osd_write(lconfig->xsize, OSD_VIDWIN0XL);
 		/*
 		 * For YUV420P format the register contents are
 		 * duplicated in both VID registers
@@ -1893,39 +2008,10 @@  static void _davinci_disp_set_layer_config(enum davinci_disp_layer layer,
 					  OSD_MISCCTL);
 				osd_write(lconfig->line_length >> 5,
 					  OSD_VIDWIN1OFST);
-				osd_write(lconfig->xpos, OSD_VIDWIN1XP);
-				osd_write(lconfig->xsize, OSD_VIDWIN1XL);
-				/* if NV21 pixfmt and line length not 32B
-				 * aligned (e.g. NTSC), Need to set window
-				 * X pixel size to be 32B aligned as well
-				 */
-				if (lconfig->xsize % 32) {
-					osd_write(((lconfig->xsize + 31) & ~31),
-						  OSD_VIDWIN1XL);
-					osd_write(((lconfig->xsize + 31) & ~31),
-						  OSD_VIDWIN0XL);
-				}
 			} else
 				osd_merge(OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D,
 					  OSD_MISCCTL);
 		}
-		if (lconfig->interlaced) {
-			osd_write(lconfig->ypos >> 1, OSD_VIDWIN0YP);
-			osd_write(lconfig->ysize >> 1, OSD_VIDWIN0YL);
-			if (cpu_is_davinci_dm365()
-			    && lconfig->pixfmt == PIXFMT_NV12) {
-				osd_write(lconfig->ypos >> 1, OSD_VIDWIN1YP);
-				osd_write(lconfig->ysize >> 1, OSD_VIDWIN1YL);
-			}
-		} else {
-			osd_write(lconfig->ypos, OSD_VIDWIN0YP);
-			osd_write(lconfig->ysize, OSD_VIDWIN0YL);
-			if (cpu_is_davinci_dm365()
-			    && lconfig->pixfmt == PIXFMT_NV12) {
-				osd_write(lconfig->ypos, OSD_VIDWIN1YP);
-				osd_write(lconfig->ysize, OSD_VIDWIN1YL);
-			}
-		}
 		break;
 	case WIN_OSD1:
 		/*
@@ -1999,15 +2085,6 @@  static void _davinci_disp_set_layer_config(enum davinci_disp_layer layer,
 
 		osd_merge(winmd_mask, winmd, OSD_OSDWIN1MD);
 		osd_write(lconfig->line_length >> 5, OSD_OSDWIN1OFST);
-		osd_write(lconfig->xpos, OSD_OSDWIN1XP);
-		osd_write(lconfig->xsize, OSD_OSDWIN1XL);
-		if (lconfig->interlaced) {
-			osd_write(lconfig->ypos >> 1, OSD_OSDWIN1YP);
-			osd_write(lconfig->ysize >> 1, OSD_OSDWIN1YL);
-		} else {
-			osd_write(lconfig->ypos, OSD_OSDWIN1YP);
-			osd_write(lconfig->ysize, OSD_OSDWIN1YL);
-		}
 		break;
 	case WIN_VID1:
 		winmd_mask |= OSD_VIDWINMD_VFF1;
@@ -2016,8 +2093,6 @@  static void _davinci_disp_set_layer_config(enum davinci_disp_layer layer,
 
 		osd_merge(winmd_mask, winmd, OSD_VIDWINMD);
 		osd_write(lconfig->line_length >> 5, OSD_VIDWIN1OFST);
-		osd_write(lconfig->xpos, OSD_VIDWIN1XP);
-		osd_write(lconfig->xsize, OSD_VIDWIN1XL);
 		/*
 		 * For YUV420P format the register contents are
 		 * duplicated in both VID registers
@@ -2035,32 +2110,13 @@  static void _davinci_disp_set_layer_config(enum davinci_disp_layer layer,
 					  OSD_MISCCTL);
 				osd_write(lconfig->line_length >> 5,
 					  OSD_VIDWIN0OFST);
-				osd_write(lconfig->xpos, OSD_VIDWIN0XP);
-				osd_write(lconfig->xsize, OSD_VIDWIN0XL);
 		} else
 			osd_merge(OSD_MISCCTL_S420D, ~OSD_MISCCTL_S420D,
 				  OSD_MISCCTL);
 		}
-
-		if (lconfig->interlaced) {
-			osd_write(lconfig->ypos >> 1, OSD_VIDWIN1YP);
-			osd_write(lconfig->ysize >> 1, OSD_VIDWIN1YL);
-			if (cpu_is_davinci_dm365()
-			    && lconfig->pixfmt == PIXFMT_NV12) {
-				osd_write(lconfig->ypos >> 1, OSD_VIDWIN0YP);
-				osd_write(lconfig->ysize >> 1, OSD_VIDWIN0YL);
-			}
-		} else {
-			osd_write(lconfig->ypos, OSD_VIDWIN1YP);
-			osd_write(lconfig->ysize, OSD_VIDWIN1YL);
-			if (cpu_is_davinci_dm365()
-			    && lconfig->pixfmt == PIXFMT_NV12) {
-				osd_write(lconfig->ypos, OSD_VIDWIN0YP);
-				osd_write(lconfig->ysize, OSD_VIDWIN0YL);
-			}
-		}
 		break;
 	}
+	davinci_disp_set_vid_size(layer, lconfig);
 }
 
 int davinci_disp_set_layer_config(enum davinci_disp_layer layer,