diff options
author | Guoniu.Zhou <guoniu.zhou@nxp.com> | 2017-08-18 10:09:08 +0800 |
---|---|---|
committer | Guoniu.Zhou <guoniu.zhou@nxp.com> | 2017-08-18 17:34:53 +0800 |
commit | bd6d2152e9486e7946d3cda5ee39808e5ea9edc3 (patch) | |
tree | 2b1a14b74816208b723e9fe2008dd8884fe2192f | |
parent | ec6fac8e63a449e92c362df407e3e8357b32fedd (diff) |
MLK-16217: PXP: fix pxp rotate yuv formate video issue
Because of IC limitation, pxp only can use rotation0 engine to
do rotation operation.
Correct coordinate settings of ps and out buffer.
Signed-off-by: Guoniu.Zhou <guoniu.zhou@nxp.com>
Reviewed-by: Robby Cai <robby.cai@nxp.com>
Reviewed-by: Fancy Fang <chen.fang@nxp.com>
-rw-r--r-- | drivers/dma/pxp/pxp_dma_v3.c | 63 |
1 files changed, 54 insertions, 9 deletions
diff --git a/drivers/dma/pxp/pxp_dma_v3.c b/drivers/dma/pxp/pxp_dma_v3.c index b73d6eabf086..9aec499e4c5b 100644 --- a/drivers/dma/pxp/pxp_dma_v3.c +++ b/drivers/dma/pxp/pxp_dma_v3.c @@ -2296,9 +2296,6 @@ static uint32_t ps_calc_scaling(struct pxp_pixmap *input, output->crop.height; } - if ((input->rotate == 90) || (input->rotate == 270)) - swap(output->crop.width, output->crop.height); - return *(uint32_t *)&scale; } @@ -2312,9 +2309,37 @@ static int pxp_ps_config(struct pxp_pixmap *input, memset((void*)&ctrl, 0x0, sizeof(ctrl)); ctrl.format = pxp_parse_ps_fmt(input->format); - out_ps_ulc.x = out_ps_ulc.y = 0; - out_ps_lrc.x = output->crop.width - 1; - out_ps_lrc.y = output->crop.height - 1; + + switch (output->rotate) { + case 0: + out_ps_ulc.x = output->crop.x; + out_ps_ulc.y = output->crop.y; + out_ps_lrc.x = output->crop.width - 1; + out_ps_lrc.y = output->crop.height - 1; + break; + case 90: + out_ps_ulc.x = output->crop.y; + out_ps_ulc.y = output->width - (output->crop.x + output->crop.width); + out_ps_lrc.x = out_ps_ulc.x + output->crop.height - 1; + out_ps_lrc.y = out_ps_ulc.y + output->crop.width - 1; + break; + case 180: + out_ps_ulc.x = output->width - (output->crop.x + output->crop.width); + out_ps_ulc.y = output->height - (output->crop.y + output->crop.height); + out_ps_lrc.x = out_ps_ulc.x + output->crop.width - 1; + out_ps_lrc.y = out_ps_ulc.y + output->crop.height - 1; + break; + case 270: + out_ps_ulc.x = output->height - (output->crop.y + output->crop.height); + out_ps_ulc.y = output->crop.x; + out_ps_lrc.x = out_ps_ulc.x + output->crop.height - 1; + out_ps_lrc.y = out_ps_ulc.y + output->crop.width - 1; + break; + default: + pr_err("PxP only support rotate 0 90 180 270\n"); + return -EINVAL; + break; + } if ((input->format == PXP_PIX_FMT_YUYV) || (input->format == PXP_PIX_FMT_YVYU)) @@ -2546,12 +2571,15 @@ static int pxp_rotation1_config(struct pxp_pixmap *input) static int pxp_rotation0_config(struct pxp_pixmap *input) { + uint8_t rotate; + if (input->flip == PXP_H_FLIP) pxp_writel(BF_PXP_CTRL_HFLIP0(1), HW_PXP_CTRL_SET); else if (input->flip == PXP_V_FLIP) pxp_writel(BF_PXP_CTRL_VFLIP0(1), HW_PXP_CTRL_SET); - pxp_writel(BF_PXP_CTRL_ROTATE0(input->rotate), HW_PXP_CTRL_SET); + rotate = rotate_map(input->rotate); + pxp_writel(BF_PXP_CTRL_ROTATE0(rotate), HW_PXP_CTRL_SET); pxp_writel(BF_PXP_CTRL_ENABLE_ROTATE0(1), HW_PXP_CTRL_SET); @@ -2600,8 +2628,14 @@ static int pxp_out_config(struct pxp_pixmap *output) pxp_writel(UV + (offset >> 1), HW_PXP_OUT_BUF2); } - out_lrc.x = output->crop.width - 1; - out_lrc.y = output->crop.height - 1; + if (output->rotate == 90 || output->rotate == 270) { + out_lrc.y = output->width - 1; + out_lrc.x = output->height - 1; + } else { + out_lrc.x = output->width - 1; + out_lrc.y = output->height - 1; + } + pxp_writel(*(uint32_t *)&out_lrc, HW_PXP_OUT_LRC); pxp_writel(output->pitch, HW_PXP_OUT_PITCH); @@ -3090,6 +3124,17 @@ reparse: nodes_in_path = find_best_path(possible_inputs, possible_outputs, input, &nodes_used); + + if (nodes_in_path & (1 << PXP_2D_ROTATION1)) { + clear_bit(PXP_2D_ROTATION1, (unsigned long *)&nodes_in_path); + set_bit(PXP_2D_ROTATION0, (unsigned long *)&nodes_in_path); + } + + if (nodes_used & (1 << PXP_2D_ROTATION1)) { + clear_bit(PXP_2D_ROTATION1, (unsigned long *)&nodes_used); + set_bit(PXP_2D_ROTATION0, (unsigned long *)&nodes_used); + } + pr_debug("%s: nodes_in_path = 0x%x, nodes_used = 0x%x\n", __func__, nodes_in_path, nodes_used); if (!nodes_used) { |