aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFancy Fang <chen.fang@freescale.com>2014-03-31 05:56:53 -0400
committerNitin Garg <nitin.garg@freescale.com>2014-04-16 09:58:15 -0400
commit32bae54b1005e55307388e9400280386d09abb6f (patch)
treeac9735866d402b2db3c8d9d298b71a183be57e53
parenteb31153ebe9d98700aa203fb859ecd065692e61d (diff)
ENGR00304418 [V4l2][PXP] Add some rotation cases support for V4L app.
Some V4L2 apps require that playing rotated fullscreen video on the screen. In recent PXP driver, this is not supported yet. So this patch adds it on through combining rotation and resize together. Signed-off-by: Fancy Fang <chen.fang@freescale.com>
-rw-r--r--drivers/dma/pxp/pxp_dma_v2.c55
-rw-r--r--drivers/media/platform/mxc/output/mxc_pxp_v4l2.c24
2 files changed, 61 insertions, 18 deletions
diff --git a/drivers/dma/pxp/pxp_dma_v2.c b/drivers/dma/pxp/pxp_dma_v2.c
index ffc76852670e..3b12b5c79a09 100644
--- a/drivers/dma/pxp/pxp_dma_v2.c
+++ b/drivers/dma/pxp/pxp_dma_v2.c
@@ -402,12 +402,23 @@ static void pxp_set_outbuf(struct pxps *pxp)
402{ 402{
403 struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state; 403 struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
404 struct pxp_layer_param *out_params = &pxp_conf->out_param; 404 struct pxp_layer_param *out_params = &pxp_conf->out_param;
405 struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
405 406
406 __raw_writel(out_params->paddr, pxp->base + HW_PXP_OUT_BUF); 407 __raw_writel(out_params->paddr, pxp->base + HW_PXP_OUT_BUF);
407 408
408 __raw_writel(BF_PXP_OUT_LRC_X(out_params->width - 1) | 409 if (proc_data->rotate == 90 || proc_data->rotate == 270) {
409 BF_PXP_OUT_LRC_Y(out_params->height - 1), 410 if (proc_data->rot_pos == 0)
410 pxp->base + HW_PXP_OUT_LRC); 411 __raw_writel(BF_PXP_OUT_LRC_X(proc_data->drect.width - 1) |
412 BF_PXP_OUT_LRC_Y(proc_data->drect.height - 1),
413 pxp->base + HW_PXP_OUT_LRC);
414 else
415 __raw_writel(BF_PXP_OUT_LRC_X(proc_data->drect.width - 1) |
416 BF_PXP_OUT_LRC_Y(proc_data->drect.height - 1),
417 pxp->base + HW_PXP_OUT_LRC);
418 } else
419 __raw_writel(BF_PXP_OUT_LRC_X(proc_data->drect.width - 1) |
420 BF_PXP_OUT_LRC_Y(proc_data->drect.height - 1),
421 pxp->base + HW_PXP_OUT_LRC);
411 422
412 if (out_params->pixel_fmt == PXP_PIX_FMT_RGB24) { 423 if (out_params->pixel_fmt == PXP_PIX_FMT_RGB24) {
413 __raw_writel(out_params->stride * 3, 424 __raw_writel(out_params->stride * 3,
@@ -574,8 +585,27 @@ static void pxp_set_s0param(struct pxps *pxp)
574{ 585{
575 struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state; 586 struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state;
576 struct pxp_proc_data *proc_data = &pxp_conf->proc_data; 587 struct pxp_proc_data *proc_data = &pxp_conf->proc_data;
588 struct pxp_layer_param *out_params = &pxp_conf->out_param;
577 u32 s0param; 589 u32 s0param;
578 590
591 if (proc_data->drect.left != 0 || proc_data->drect.top != 0) {
592 out_params->paddr += (proc_data->drect.top * out_params->stride +
593 proc_data->drect.left) * 2;
594 proc_data->drect.left = proc_data->drect.top = 0;
595 }
596
597 /* Since user apps always pass the rotated drect
598 * to this driver, we need to first swap the width
599 * and height which is used to calculate the scale
600 * factors later.
601 */
602 if (proc_data->rotate == 90 || proc_data->rotate == 270) {
603 int temp;
604 temp = proc_data->drect.width;
605 proc_data->drect.width = proc_data->drect.height;
606 proc_data->drect.height = temp;
607 }
608
579 /* contains the coordinate for the PS in the OUTPUT buffer. */ 609 /* contains the coordinate for the PS in the OUTPUT buffer. */
580 if ((pxp_conf->s0_param).width == 0 && 610 if ((pxp_conf->s0_param).width == 0 &&
581 (pxp_conf->s0_param).height == 0) { 611 (pxp_conf->s0_param).height == 0) {
@@ -585,10 +615,21 @@ static void pxp_set_s0param(struct pxps *pxp)
585 s0param = BF_PXP_OUT_PS_ULC_X(proc_data->drect.left); 615 s0param = BF_PXP_OUT_PS_ULC_X(proc_data->drect.left);
586 s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.top); 616 s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.top);
587 __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_ULC); 617 __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_ULC);
588 s0param = BF_PXP_OUT_PS_LRC_X(proc_data->drect.left + 618 /* In PXP, the two different rotation
589 proc_data->drect.width - 1); 619 * position requires different settings
590 s0param |= BF_PXP_OUT_PS_LRC_Y(proc_data->drect.top + 620 * on OUT_PS_LRC register
591 proc_data->drect.height - 1); 621 */
622 if (proc_data->rot_pos == 1) {
623 s0param = BF_PXP_OUT_PS_LRC_X(proc_data->drect.left +
624 proc_data->drect.height - 1);
625 s0param |= BF_PXP_OUT_PS_LRC_Y(proc_data->drect.top +
626 proc_data->drect.width - 1);
627 } else {
628 s0param = BF_PXP_OUT_PS_LRC_X(proc_data->drect.left +
629 proc_data->drect.width - 1);
630 s0param |= BF_PXP_OUT_PS_LRC_Y(proc_data->drect.top +
631 proc_data->drect.height - 1);
632 }
592 __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_LRC); 633 __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_LRC);
593 } 634 }
594} 635}
diff --git a/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c
index 56a09d382320..64c06fcb7c55 100644
--- a/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c
+++ b/drivers/media/platform/mxc/output/mxc_pxp_v4l2.c
@@ -450,6 +450,7 @@ static int pxp_s_output(struct file *file, void *fh,
450 if (ret < 0) 450 if (ret < 0)
451 return ret; 451 return ret;
452 } 452 }
453 memset(pxp->outbuf.vaddr, 0x0, pxp->outbuf.size);
453 454
454 pxp->pxp_conf.out_param.width = fmt->width; 455 pxp->pxp_conf.out_param.width = fmt->width;
455 pxp->pxp_conf.out_param.height = fmt->height; 456 pxp->pxp_conf.out_param.height = fmt->height;
@@ -811,17 +812,14 @@ static int pxp_buf_prepare(struct videobuf_queue *q,
811 &pxp_conf->s0_param, 812 &pxp_conf->s0_param,
812 sizeof(struct pxp_layer_param)); 813 sizeof(struct pxp_layer_param));
813 } else if (i == 1) { /* Output */ 814 } else if (i == 1) { /* Output */
814 if (proc_data->rotate % 180) { 815 /* we should always pass the output
815 pxp_conf->out_param.width = 816 * width and height which is the value
816 pxp->fb.fmt.height; 817 * after been rotated.
817 pxp_conf->out_param.height = 818 */
818 pxp->fb.fmt.width; 819 pxp_conf->out_param.width =
819 } else { 820 pxp->fb.fmt.width;
820 pxp_conf->out_param.width = 821 pxp_conf->out_param.height =
821 pxp->fb.fmt.width; 822 pxp->fb.fmt.height;
822 pxp_conf->out_param.height =
823 pxp->fb.fmt.height;
824 }
825 823
826 pxp_conf->out_param.paddr = pxp->outbuf.paddr; 824 pxp_conf->out_param.paddr = pxp->outbuf.paddr;
827 memcpy(&desc->layer_param.out_param, 825 memcpy(&desc->layer_param.out_param,
@@ -1036,6 +1034,8 @@ static int pxp_s_crop(struct file *file, void *fh,
1036 pxp->pxp_conf.proc_data.drect.width = w; 1034 pxp->pxp_conf.proc_data.drect.width = w;
1037 pxp->pxp_conf.proc_data.drect.height = h; 1035 pxp->pxp_conf.proc_data.drect.height = h;
1038 1036
1037 memset(pxp->outbuf.vaddr, 0x0, pxp->outbuf.size);
1038
1039 return 0; 1039 return 0;
1040} 1040}
1041 1041
@@ -1081,6 +1081,8 @@ static int pxp_s_ctrl(struct file *file, void *priv,
1081 return pxp_set_cstate(pxp, vc); 1081 return pxp_set_cstate(pxp, vc);
1082 } 1082 }
1083 1083
1084 memset(pxp->outbuf.vaddr, 0x0, pxp->outbuf.size);
1085
1084 return -EINVAL; 1086 return -EINVAL;
1085} 1087}
1086 1088