diff options
author | Robby Cai <R63905@freescale.com> | 2012-10-15 21:36:44 +0800 |
---|---|---|
committer | Robby Cai <R63905@freescale.com> | 2012-10-23 11:07:06 +0800 |
commit | cc16b670283afdd19d553b92f8523db96819a9ac (patch) | |
tree | a10ffb6665346c828408db4bd9de1cd5ab5692a9 | |
parent | 184c49cb3d7b2620e3b31688e1eec1649b46b6dc (diff) |
ENGR00229665 pxp: correct crop setting
The settings in the PXP_PS_BUF, PXP_OUT_PS_ULC, and PXP_OUT_PS_LRC will
determine the subset of the PS buffer, or clipped PS source buffer, that
will be used in the output buffer.
HW_PXP_OUT_PS_LRC should set the scaled output size rather than the origin
size when scaling.
Please refer to the "Clipping source images" section in RM for how it works.
Signed-off-by: Robby Cai <R63905@freescale.com>
-rw-r--r-- | drivers/dma/pxp/pxp_dma_v2.c | 42 |
1 files changed, 32 insertions, 10 deletions
diff --git a/drivers/dma/pxp/pxp_dma_v2.c b/drivers/dma/pxp/pxp_dma_v2.c index b74f62cac032..c6098774ecf2 100644 --- a/drivers/dma/pxp/pxp_dma_v2.c +++ b/drivers/dma/pxp/pxp_dma_v2.c @@ -436,22 +436,27 @@ static void pxp_set_olparam(int layer_no, struct pxps *pxp) static void pxp_set_s0param(struct pxps *pxp) { struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state; - struct pxp_layer_param *s0params_data = &pxp_conf->s0_param; struct pxp_proc_data *proc_data = &pxp_conf->proc_data; u32 s0param; - s0param = BF_PXP_OUT_PS_ULC_X(proc_data->srect.left); - s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->srect.top); + /* contains the coordinate for the PS in the OUTPUT buffer. */ + s0param = BF_PXP_OUT_PS_ULC_X(proc_data->drect.left); + s0param |= BF_PXP_OUT_PS_ULC_Y(proc_data->drect.top); __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_ULC); - s0param = BF_PXP_OUT_PS_LRC_X(s0params_data->width); - s0param |= BF_PXP_OUT_PS_LRC_Y(s0params_data->height); + s0param = BF_PXP_OUT_PS_LRC_X(proc_data->drect.left + + proc_data->drect.width - 1); + s0param |= BF_PXP_OUT_PS_LRC_Y(proc_data->drect.top + + proc_data->drect.height - 1); __raw_writel(s0param, pxp->base + HW_PXP_OUT_PS_LRC); - } -/* TODO: crop behavior is re-designed in h/w. */ +/* crop behavior is re-designed in h/w. */ static void pxp_set_s0crop(struct pxps *pxp) { + /* + * place-holder, it's implemented in other functions in this driver. + * Refer to "Clipping source images" section in RM for detail. + */ } static int pxp_set_scaling(struct pxps *pxp) @@ -706,19 +711,36 @@ static void pxp_set_s0buf(struct pxps *pxp) { struct pxp_config_data *pxp_conf = &pxp->pxp_conf_state; struct pxp_layer_param *s0_params = &pxp_conf->s0_param; + struct pxp_proc_data *proc_data = &pxp_conf->proc_data; dma_addr_t Y, U, V; + dma_addr_t Y1, U1, V1; + u32 offset, bpp = 1; Y = s0_params->paddr; - __raw_writel(Y, pxp->base + HW_PXP_PS_BUF); + + if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB565) + bpp = 2; + else if (s0_params->pixel_fmt == PXP_PIX_FMT_RGB24) + bpp = 4; + offset = (proc_data->srect.top * s0_params->width + + proc_data->srect.left) * bpp; + /* clipping or cropping */ + Y1 = Y + offset; + __raw_writel(Y1, pxp->base + HW_PXP_PS_BUF); if ((s0_params->pixel_fmt == PXP_PIX_FMT_YUV420P) || (s0_params->pixel_fmt == PXP_PIX_FMT_YVU420P) || (s0_params->pixel_fmt == PXP_PIX_FMT_GREY)) { /* Set to 1 if YUV format is 4:2:2 rather than 4:2:0 */ int s = 2; + + offset = proc_data->srect.top * s0_params->width / 4 + + proc_data->srect.left / 2; U = Y + (s0_params->width * s0_params->height); + U1 = U + offset; V = U + ((s0_params->width * s0_params->height) >> s); - __raw_writel(U, pxp->base + HW_PXP_PS_UBUF); - __raw_writel(V, pxp->base + HW_PXP_PS_VBUF); + V1 = V + offset; + __raw_writel(U1, pxp->base + HW_PXP_PS_UBUF); + __raw_writel(V1, pxp->base + HW_PXP_PS_VBUF); } /* TODO: only support RGB565, Y8, Y4, YUV420 */ |