[PATCH 09/20] video: msm: Split out MDP2.2 HW specific code.
Janorkar, Mayuresh
mayur at ti.com
Mon Mar 21 01:15:15 EDT 2011
> -----Original Message-----
> From: linux-fbdev-owner at vger.kernel.org [mailto:linux-fbdev-
> owner at vger.kernel.org] On Behalf Of Carl Vanderlip
> Sent: Saturday, March 19, 2011 3:27 AM
> To: Russell King; David Brown; Daniel Walker; Bryan Huntsman
> Cc: Brian Swetland; Dima Zavin; Rebecca Schultz Zavin; Colin Cross; linux-
> fbdev at vger.kernel.org; Carl Vanderlip; linux-arm-
> kernel at lists.infradead.org; linux-arm-msm at vger.kernel.org; linux-
> kernel at vger.kernel.org
> Subject: [PATCH 09/20] video: msm: Split out MDP2.2 HW specific code.
>
> Moving MDP2.2 HW specific code allows for reuse of PPP code
> when adding other MDP HW versions. Splitting also begins
> simplification of mdp_probe function.
>
> Authors:
> Dima Zavin <dima at android.com>
> Rebecca Schultz Zavin <rebecca at android.com>
> Colin Cross <ccross at android.com>
>
> Signed-off-by: Carl Vanderlip <carlv at codeaurora.org>
> ---
> arch/arm/mach-msm/Kconfig | 5 +
> drivers/video/msm/Makefile | 4 +-
> drivers/video/msm/mdp.c | 14 +-
> drivers/video/msm/mdp_ppp.c | 358 ++++-----------
> -----
> drivers/video/msm/mdp_ppp.h | 12 +
> .../video/msm/{mdp_scale_tables.c => mdp_ppp22.c} | 333
> ++++++++++++++++++-
> drivers/video/msm/mdp_scale_tables.h | 38 --
> 7 files changed, 417 insertions(+), 347 deletions(-)
> rename drivers/video/msm/{mdp_scale_tables.c => mdp_ppp22.c} (69%)
> delete mode 100644 drivers/video/msm/mdp_scale_tables.h
>
> diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
> index df9d74e..d6e75c3 100644
> --- a/arch/arm/mach-msm/Kconfig
> +++ b/arch/arm/mach-msm/Kconfig
> @@ -76,6 +76,11 @@ config HAS_MSM_DEBUG_UART_PHYS
> config MSM_VIC
> bool
>
> +config MSM_MDP22
> + bool
> + depends on ARCH_MSM7X00A
> + default y
Please add some help here.
> +
> menu "Qualcomm MSM Board Type"
>
> config MACH_HALIBUT
> diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
> index 802d6ae..0666aef 100644
> --- a/drivers/video/msm/Makefile
> +++ b/drivers/video/msm/Makefile
> @@ -5,7 +5,9 @@ obj-y := msm_fb.o
>
> # MDP DMA/PPP engine
> #
> -obj-y += mdp.o mdp_scale_tables.o mdp_ppp.o
> +obj-y += mdp.o mdp_ppp.o
> +
> +obj-$(CONFIG_MSM_MDP22) += mdp_ppp22.o
>
> # MDDI interface
> #
> diff --git a/drivers/video/msm/mdp.c b/drivers/video/msm/mdp.c
> index 765df06..6aa9ed5 100644
> --- a/drivers/video/msm/mdp.c
> +++ b/drivers/video/msm/mdp.c
> @@ -30,6 +30,7 @@
> #include <linux/platform_device.h>
>
> #include "mdp_hw.h"
> +#include "mdp_ppp.h"
>
> struct class *mdp_class;
>
> @@ -453,7 +454,13 @@ int register_mdp_client(struct class_interface *cint)
> }
>
> #include "mdp_csc_table.h"
> -#include "mdp_scale_tables.h"
> +
> +void mdp_hw_init(struct mdp_info *mdp)
> +{
> +#ifdef CONFIG_MSM_MDP22
> + mdp_ppp_init_scale(mdp);
> +#endif
> +}
>
> int mdp_probe(struct platform_device *pdev)
> {
> @@ -551,15 +558,12 @@ int mdp_probe(struct platform_device *pdev)
> mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e0);
> mdp_writel(mdp, 0, MDP_CMD_DEBUG_ACCESS_BASE + 0x01e4);
>
> - for (n = 0; n < ARRAY_SIZE(mdp_upscale_table); n++)
> - mdp_writel(mdp, mdp_upscale_table[n].val,
> - mdp_upscale_table[n].reg);
> -
> for (n = 0; n < 9; n++)
> mdp_writel(mdp, mdp_default_ccs[n], 0x40440 + 4 * n);
> mdp_writel(mdp, mdp_default_ccs[9], 0x40500 + 4 * 0);
> mdp_writel(mdp, mdp_default_ccs[10], 0x40500 + 4 * 0);
> mdp_writel(mdp, mdp_default_ccs[11], 0x40500 + 4 * 0);
> + mdp_hw_init(mdp);
>
> /* register mdp device */
> mdp->mdp_dev.dev.parent = &pdev->dev;
> diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/msm/mdp_ppp.c
> index 05f3e33..3d190b9 100644
> --- a/drivers/video/msm/mdp_ppp.c
> +++ b/drivers/video/msm/mdp_ppp.c
> @@ -20,14 +20,14 @@
>
> #include "mdp_hw.h"
> #include "mdp_ppp.h"
> -#include "mdp_scale_tables.h"
>
> #define DLOG(x...) do {} while (0)
>
> -#define MDP_DOWNSCALE_BLUR (MDP_DOWNSCALE_MAX + 1)
> -static int downscale_y_table = MDP_DOWNSCALE_MAX;
> -static int downscale_x_table = MDP_DOWNSCALE_MAX;
> +#define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp)
>
> +#define Y_TO_CRCB_RATIO(format) \
> + ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CRCB_H2V2) ? 2 :\
> + (format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ? 1 : 1)
>
> static uint32_t pack_pattern[] = {
> PPP_ARRAY0(PACK_PATTERN)
> @@ -67,6 +67,19 @@ static uint32_t bg_op_chroma[] = {
> PPP_ARRAY1(CHROMA_SAMP, BG)
> };
>
> +static void set_src_region(struct mdp_img *img, struct mdp_rect *rect,
> + struct ppp_regs *regs)
> +{
> + regs->src_rect = (rect->h << 16) | (rect->w & 0x1fff);
> +
[cosmetic comment]: unnecessary extra line?
> +}
> +
> +static inline void set_dst_region(struct mdp_rect *rect, struct ppp_regs
> *regs)
> +{
> + regs->dst_rect = (rect->h << 16) | (rect->w & 0xfff);
> +
[cosmetic comment]: unnecessary extra line?
> +}
> +
> static void rotate_dst_addr_x(struct mdp_blit_req *req,
> struct ppp_regs *regs)
> {
> @@ -181,254 +194,30 @@ static void blit_blend(struct mdp_blit_req *req,
> struct ppp_regs *regs)
> }
>
> regs->op |= bg_op_chroma[req->dst.format];
> -}
> -
> -#define ONE_HALF (1LL << 32)
> -#define ONE (1LL << 33)
> -#define TWO (2LL << 33)
> -#define THREE (3LL << 33)
> -#define FRAC_MASK (ONE - 1)
> -#define INT_MASK (~FRAC_MASK)
> -
> -static int scale_params(uint32_t dim_in, uint32_t dim_out, uint32_t
> origin,
> - uint32_t *phase_init, uint32_t *phase_step)
> -{
> - /* to improve precicsion calculations are done in U31.33 and
> converted
> - * to U3.29 at the end */
> - int64_t k1, k2, k3, k4, tmp;
> - uint64_t n, d, os, os_p, od, od_p, oreq;
> - unsigned rpa = 0;
> - int64_t ip64, delta;
> -
> - if (dim_out % 3 == 0)
> - rpa = !(dim_in % (dim_out / 3));
> -
> - n = ((uint64_t)dim_out) << 34;
> - d = dim_in;
> - if (!d)
> - return -1;
> - do_div(n, d);
> - k3 = (n + 1) >> 1;
> - if ((k3 >> 4) < (1LL << 27) || (k3 >> 4) > (1LL << 31)) {
> - DLOG("crap bad scale\n");
> - return -1;
> - }
> - n = ((uint64_t)dim_in) << 34;
> - d = (uint64_t)dim_out;
> - if (!d)
> - return -1;
> - do_div(n, d);
> - k1 = (n + 1) >> 1;
> - k2 = (k1 - ONE) >> 1;
> -
> - *phase_init = (int)(k2 >> 4);
> - k4 = (k3 - ONE) >> 1;
> -
> - if (rpa) {
> - os = ((uint64_t)origin << 33) - ONE_HALF;
> - tmp = (dim_out * os) + ONE_HALF;
> - if (!dim_in)
> - return -1;
> - do_div(tmp, dim_in);
> - od = tmp - ONE_HALF;
> - } else {
> - os = ((uint64_t)origin << 1) - 1;
> - od = (((k3 * os) >> 1) + k4);
> - }
> -
> - od_p = od & INT_MASK;
> - if (od_p != od)
> - od_p += ONE;
> -
> - if (rpa) {
> - tmp = (dim_in * od_p) + ONE_HALF;
> - if (!dim_in)
> - return -1;
> - do_div(tmp, dim_in);
> - os_p = tmp - ONE_HALF;
> - } else {
> - os_p = ((k1 * (od_p >> 33)) + k2);
> - }
> -
> - oreq = (os_p & INT_MASK) - ONE;
> -
> - ip64 = os_p - oreq;
> - delta = ((int64_t)(origin) << 33) - oreq;
> - ip64 -= delta;
> - /* limit to valid range before the left shift */
> - delta = (ip64 & (1LL << 63)) ? 4 : -4;
> - delta <<= 33;
> - while (abs((int)(ip64 >> 33)) > 4)
> - ip64 += delta;
> - *phase_init = (int)(ip64 >> 4);
> - *phase_step = (uint32_t)(k1 >> 4);
> - return 0;
> -}
> -
> -static void load_scale_table(const struct mdp_info *mdp,
> - struct mdp_table_entry *table, int len)
> -{
> - int i;
> - for (i = 0; i < len; i++)
> - mdp_writel(mdp, table[i].val, table[i].reg);
> -}
> -
> -enum {
> -IMG_LEFT,
> -IMG_RIGHT,
> -IMG_TOP,
> -IMG_BOTTOM,
> -};
> -
> -static void get_edge_info(uint32_t src, uint32_t src_coord, uint32_t dst,
> - uint32_t *interp1, uint32_t *interp2,
> - uint32_t *repeat1, uint32_t *repeat2) {
> - if (src > 3 * dst) {
> - *interp1 = 0;
> - *interp2 = src - 1;
> - *repeat1 = 0;
> - *repeat2 = 0;
> - } else if (src == 3 * dst) {
> - *interp1 = 0;
> - *interp2 = src;
> - *repeat1 = 0;
> - *repeat2 = 1;
> - } else if (src > dst && src < 3 * dst) {
> - *interp1 = -1;
> - *interp2 = src;
> - *repeat1 = 1;
> - *repeat2 = 1;
> - } else if (src == dst) {
> - *interp1 = -1;
> - *interp2 = src + 1;
> - *repeat1 = 1;
> - *repeat2 = 2;
> - } else {
> - *interp1 = -2;
> - *interp2 = src + 1;
> - *repeat1 = 2;
> - *repeat2 = 2;
> - }
> - *interp1 += src_coord;
> - *interp2 += src_coord;
> -}
> -
> -static int get_edge_cond(struct mdp_blit_req *req, struct ppp_regs *regs)
> -{
> - int32_t luma_interp[4];
> - int32_t luma_repeat[4];
> - int32_t chroma_interp[4];
> - int32_t chroma_bound[4];
> - int32_t chroma_repeat[4];
> - uint32_t dst_w, dst_h;
> -
> - memset(&luma_interp, 0, sizeof(int32_t) * 4);
> - memset(&luma_repeat, 0, sizeof(int32_t) * 4);
> - memset(&chroma_interp, 0, sizeof(int32_t) * 4);
> - memset(&chroma_bound, 0, sizeof(int32_t) * 4);
> - memset(&chroma_repeat, 0, sizeof(int32_t) * 4);
> - regs->edge = 0;
> -
> - if (req->flags & MDP_ROT_90) {
> - dst_w = req->dst_rect.h;
> - dst_h = req->dst_rect.w;
> - } else {
> - dst_w = req->dst_rect.w;
> - dst_h = req->dst_rect.h;
> - }
> -
> - if (regs->op & (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON)) {
> - get_edge_info(req->src_rect.h, req->src_rect.y, dst_h,
> - &luma_interp[IMG_TOP], &luma_interp[IMG_BOTTOM],
> - &luma_repeat[IMG_TOP], &luma_repeat[IMG_BOTTOM]);
> - get_edge_info(req->src_rect.w, req->src_rect.x, dst_w,
> - &luma_interp[IMG_LEFT], &luma_interp[IMG_RIGHT],
> - &luma_repeat[IMG_LEFT], &luma_repeat[IMG_RIGHT]);
> - } else {
> - luma_interp[IMG_LEFT] = req->src_rect.x;
> - luma_interp[IMG_RIGHT] = req->src_rect.x + req->src_rect.w -
> 1;
> - luma_interp[IMG_TOP] = req->src_rect.y;
> - luma_interp[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h -
> 1;
> - luma_repeat[IMG_LEFT] = 0;
> - luma_repeat[IMG_TOP] = 0;
> - luma_repeat[IMG_RIGHT] = 0;
> - luma_repeat[IMG_BOTTOM] = 0;
> - }
> -
> - chroma_interp[IMG_LEFT] = luma_interp[IMG_LEFT];
> - chroma_interp[IMG_RIGHT] = luma_interp[IMG_RIGHT];
> - chroma_interp[IMG_TOP] = luma_interp[IMG_TOP];
> - chroma_interp[IMG_BOTTOM] = luma_interp[IMG_BOTTOM];
> -
> - chroma_bound[IMG_LEFT] = req->src_rect.x;
> - chroma_bound[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1;
> - chroma_bound[IMG_TOP] = req->src_rect.y;
> - chroma_bound[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1;
> -
> - if (IS_YCRCB(req->src.format)) {
> - chroma_interp[IMG_LEFT] = chroma_interp[IMG_LEFT] >> 1;
> - chroma_interp[IMG_RIGHT] = (chroma_interp[IMG_RIGHT] + 1) >>
> 1;
> -
> - chroma_bound[IMG_LEFT] = chroma_bound[IMG_LEFT] >> 1;
> - chroma_bound[IMG_RIGHT] = chroma_bound[IMG_RIGHT] >> 1;
> - }
>
> - if (req->src.format == MDP_Y_CBCR_H2V2 ||
> - req->src.format == MDP_Y_CRCB_H2V2) {
> - chroma_interp[IMG_TOP] = (chroma_interp[IMG_TOP] - 1) >> 1;
> - chroma_interp[IMG_BOTTOM] = (chroma_interp[IMG_BOTTOM] + 1)
> - >> 1;
> - chroma_bound[IMG_TOP] = (chroma_bound[IMG_TOP] + 1) >> 1;
> - chroma_bound[IMG_BOTTOM] = chroma_bound[IMG_BOTTOM] >> 1;
> - }
> -
> - chroma_repeat[IMG_LEFT] = chroma_bound[IMG_LEFT] -
> - chroma_interp[IMG_LEFT];
> - chroma_repeat[IMG_RIGHT] = chroma_interp[IMG_RIGHT] -
> - chroma_bound[IMG_RIGHT];
> - chroma_repeat[IMG_TOP] = chroma_bound[IMG_TOP] -
> - chroma_interp[IMG_TOP];
> - chroma_repeat[IMG_BOTTOM] = chroma_interp[IMG_BOTTOM] -
> - chroma_bound[IMG_BOTTOM];
> -
> - if (chroma_repeat[IMG_LEFT] < 0 || chroma_repeat[IMG_LEFT] > 3 ||
> - chroma_repeat[IMG_RIGHT] < 0 || chroma_repeat[IMG_RIGHT] > 3 ||
> - chroma_repeat[IMG_TOP] < 0 || chroma_repeat[IMG_TOP] > 3 ||
> - chroma_repeat[IMG_BOTTOM] < 0 || chroma_repeat[IMG_BOTTOM] > 3
> ||
> - luma_repeat[IMG_LEFT] < 0 || luma_repeat[IMG_LEFT] > 3 ||
> - luma_repeat[IMG_RIGHT] < 0 || luma_repeat[IMG_RIGHT] > 3 ||
> - luma_repeat[IMG_TOP] < 0 || luma_repeat[IMG_TOP] > 3 ||
> - luma_repeat[IMG_BOTTOM] < 0 || luma_repeat[IMG_BOTTOM] > 3)
> - return -1;
> -
> - regs->edge |= (chroma_repeat[IMG_LEFT] & 3) << MDP_LEFT_CHROMA;
> - regs->edge |= (chroma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_CHROMA;
> - regs->edge |= (chroma_repeat[IMG_TOP] & 3) << MDP_TOP_CHROMA;
> - regs->edge |= (chroma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_CHROMA;
> - regs->edge |= (luma_repeat[IMG_LEFT] & 3) << MDP_LEFT_LUMA;
> - regs->edge |= (luma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_LUMA;
> - regs->edge |= (luma_repeat[IMG_TOP] & 3) << MDP_TOP_LUMA;
> - regs->edge |= (luma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_LUMA;
> - return 0;
> + /* since we always blend src + dst -> dst, copy most of the
> + * configuration from dest to bg */
> + regs->bg0 = regs->dst0;
> + regs->bg1 = regs->dst1;
> + regs->bg_cfg = src_img_cfg[req->dst.format];
> + regs->bg_bpp = regs->dst_bpp;
> + regs->bg_pack = pack_pattern[req->dst.format];
> + regs->bg_ystride = regs->dst_ystride;
> }
>
> static int blit_scale(const struct mdp_info *mdp, struct mdp_blit_req
> *req,
> struct ppp_regs *regs)
> {
> - uint32_t phase_init_x, phase_init_y, phase_step_x, phase_step_y;
> - uint32_t scale_factor_x, scale_factor_y;
> - uint32_t downscale;
> - uint32_t dst_w, dst_h;
> + struct mdp_rect dst_rect;
>
> + memcpy(&dst_rect, &req->dst_rect, sizeof(dst_rect));
> if (req->flags & MDP_ROT_90) {
> - dst_w = req->dst_rect.h;
> - dst_h = req->dst_rect.w;
> - } else {
> - dst_w = req->dst_rect.w;
> - dst_h = req->dst_rect.h;
> + dst_rect.w = req->dst_rect.h;
> + dst_rect.h = req->dst_rect.w;
> }
> - if ((req->src_rect.w == dst_w) && (req->src_rect.h == dst_h) &&
> - !(req->flags & MDP_BLUR)) {
> +
> + if ((req->src_rect.w == dst_rect.w) && (req->src_rect.h ==
> dst_rect.h)
> + && !(req->flags & MDP_BLUR)) {
> regs->phasex_init = 0;
> regs->phasey_init = 0;
> regs->phasex_step = 0;
> @@ -436,73 +225,35 @@ static int blit_scale(const struct mdp_info *mdp,
> struct mdp_blit_req *req,
> return 0;
> }
>
> - if (scale_params(req->src_rect.w, dst_w, 1, &phase_init_x,
> - &phase_step_x) ||
> - scale_params(req->src_rect.h, dst_h, 1, &phase_init_y,
> - &phase_step_y))
> +#ifdef CONFIG_MSM_MDP22
> + if (mdp_ppp_cfg_scale(mdp, regs, &req->src_rect, &dst_rect,
> + req->src.format, req->dst.format)) {
> + DLOG("crap, bad scale\n");
> return -1;
> -
> - scale_factor_x = (dst_w * 10) / req->src_rect.w;
> - scale_factor_y = (dst_h * 10) / req->src_rect.h;
> -
> - if (scale_factor_x > 8)
> - downscale = MDP_DOWNSCALE_PT8TO1;
> - else if (scale_factor_x > 6)
> - downscale = MDP_DOWNSCALE_PT6TOPT8;
> - else if (scale_factor_x > 4)
> - downscale = MDP_DOWNSCALE_PT4TOPT6;
> - else
> - downscale = MDP_DOWNSCALE_PT2TOPT4;
> - if (downscale != downscale_x_table) {
> - load_scale_table(mdp, mdp_downscale_x_table[downscale], 64);
> - downscale_x_table = downscale;
> }
> +#endif
>
> - if (scale_factor_y > 8)
> - downscale = MDP_DOWNSCALE_PT8TO1;
> - else if (scale_factor_y > 6)
> - downscale = MDP_DOWNSCALE_PT6TOPT8;
> - else if (scale_factor_y > 4)
> - downscale = MDP_DOWNSCALE_PT4TOPT6;
> - else
> - downscale = MDP_DOWNSCALE_PT2TOPT4;
> - if (downscale != downscale_y_table) {
> - load_scale_table(mdp, mdp_downscale_y_table[downscale], 64);
> - downscale_y_table = downscale;
> - }
> -
> - regs->phasex_init = phase_init_x;
> - regs->phasey_init = phase_init_y;
> - regs->phasex_step = phase_step_x;
> - regs->phasey_step = phase_step_y;
> regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
> return 0;
> -
> }
>
> static void blit_blur(const struct mdp_info *mdp, struct mdp_blit_req
> *req,
> struct ppp_regs *regs)
> {
> +#ifdef CONFIG_MSM_MDP22
> + int ret;
> +#endif
> if (!(req->flags & MDP_BLUR))
> return;
>
> - if (!(downscale_x_table == MDP_DOWNSCALE_BLUR &&
> - downscale_y_table == MDP_DOWNSCALE_BLUR)) {
> - load_scale_table(mdp, mdp_gaussian_blur_table, 128);
> - downscale_x_table = MDP_DOWNSCALE_BLUR;
> - downscale_y_table = MDP_DOWNSCALE_BLUR;
> - }
> -
> +#ifdef CONFIG_MSM_MDP22
> + ret = mdp_ppp_load_blur(mdp);
> + if (ret)
> + return;
> +#endif
> regs->op |= (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON);
> }
>
> -
> -#define IMG_LEN(rect_h, w, rect_w, bpp) (((rect_h) * w) * bpp)
> -
> -#define Y_TO_CRCB_RATIO(format) \
> - ((format == MDP_Y_CBCR_H2V2 || format == MDP_Y_CRCB_H2V2) ? 2 :\
> - (format == MDP_Y_CBCR_H2V1 || format == MDP_Y_CRCB_H2V1) ? 1 : 1)
> -
> static void get_len(struct mdp_img *img, struct mdp_rect *rect, uint32_t
> bpp,
> uint32_t *len0, uint32_t *len1)
> {
> @@ -555,7 +306,6 @@ static int valid_src_dst(unsigned long src_start,
> unsigned long src_len,
> return 1;
> }
>
> -
> static void flush_imgs(struct mdp_blit_req *req, struct ppp_regs *regs,
> struct file *src_file, struct file *dst_file)
> {
> @@ -643,22 +393,29 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct
> mdp_blit_req *req,
> return -EINVAL;
> }
>
> + if (unlikely(req->src_rect.x + req->src_rect.w > req->src.width ||
> + req->src_rect.y + req->src_rect.h > req->src.height ||
> + req->dst_rect.x + req->dst_rect.w > req->dst.width ||
> + req->dst_rect.y + req->dst_rect.h > req->dst.height)) {
> + printk(KERN_ERR "mdp_ppp: img rect extends outside of
> img!\n");
> + return -EINVAL;
> + }
> +
> /* set the src image configuration */
> regs.src_cfg = src_img_cfg[req->src.format];
> regs.src_cfg |= (req->src_rect.x & 0x1) ? PPP_SRC_BPP_ROI_ODD_X : 0;
> regs.src_cfg |= (req->src_rect.y & 0x1) ? PPP_SRC_BPP_ROI_ODD_Y : 0;
> - regs.src_rect = (req->src_rect.h << 16) | req->src_rect.w;
> regs.src_pack = pack_pattern[req->src.format];
>
> /* set the dest image configuration */
> regs.dst_cfg = dst_img_cfg[req->dst.format] | PPP_DST_OUT_SEL_AXI;
> - regs.dst_rect = (req->dst_rect.h << 16) | req->dst_rect.w;
> regs.dst_pack = pack_pattern[req->dst.format];
>
> /* set src, bpp, start pixel and ystride */
> regs.src_bpp = bytes_per_pixel[req->src.format];
> regs.src0 = src_start + req->src.offset;
> regs.src_ystride = req->src.width * regs.src_bpp;
> + set_src_region(&req->src, &req->src_rect, ®s);
> get_chroma_addr(&req->src, &req->src_rect, regs.src0, regs.src_bpp,
> regs.src_cfg, ®s.src1, ®s.src_ystride);
> regs.src0 += (req->src_rect.x + (req->src_rect.y * req->src.width))
> *
> @@ -668,6 +425,7 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct
> mdp_blit_req *req,
> regs.dst_bpp = bytes_per_pixel[req->dst.format];
> regs.dst0 = dst_start + req->dst.offset;
> regs.dst_ystride = req->dst.width * regs.dst_bpp;
> + set_dst_region(&req->dst_rect, ®s);
> get_chroma_addr(&req->dst, &req->dst_rect, regs.dst0, regs.dst_bpp,
> regs.dst_cfg, ®s.dst1, ®s.dst_ystride);
> regs.dst0 += (req->dst_rect.x + (req->dst_rect.y * req->dst.width))
> *
> @@ -703,9 +461,11 @@ int mdp_ppp_blit(const struct mdp_info *mdp, struct
> mdp_blit_req *req,
> req->dst_rect.x = req->dst_rect.x & (~0x1);
> req->dst_rect.w = req->dst_rect.w & (~0x1);
> }
> - if (get_edge_cond(req, ®s))
> - return -EINVAL;
>
> +#ifdef CONFIG_MSM_MDP22
> + if (mdp_ppp_cfg_edge_cond(req, ®s))
> + return -EINVAL;
> +#endif
> send_blit(mdp, req, ®s, src_file, dst_file);
> return 0;
> }
> diff --git a/drivers/video/msm/mdp_ppp.h b/drivers/video/msm/mdp_ppp.h
> index ef3b125..c3cd895 100644
> --- a/drivers/video/msm/mdp_ppp.h
> +++ b/drivers/video/msm/mdp_ppp.h
> @@ -47,4 +47,16 @@ struct ppp_regs {
> uint32_t bg_ystride;
> };
>
> +struct mdp_info;
> +struct mdp_rect;
> +struct mdp_blit_req;
> +
> +void mdp_ppp_init_scale(const struct mdp_info *mdp);
> +int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs,
> + struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
> + uint32_t src_format, uint32_t dst_format);
> +int mdp_ppp_load_blur(const struct mdp_info *mdp);
> +
> +int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs
> *regs);
> +
> #endif /* _VIDEO_MSM_MDP_PPP_H_ */
> diff --git a/drivers/video/msm/mdp_scale_tables.c
> b/drivers/video/msm/mdp_ppp22.c
> similarity index 69%
> rename from drivers/video/msm/mdp_scale_tables.c
> rename to drivers/video/msm/mdp_ppp22.c
> index 604783b..8cfcff2 100644
> --- a/drivers/video/msm/mdp_scale_tables.c
> +++ b/drivers/video/msm/mdp_ppp22.c
> @@ -1,6 +1,6 @@
> -/* drivers/video/msm_fb/mdp_scale_tables.c
> +/* drivers/video/msm/mdp_ppp22.c
> *
> - * Copyright (C) 2007 QUALCOMM Incorporated
> + * Copyright (C) 2007, 2011 Code Aurora Forum. All rights reserved.
> * Copyright (C) 2007 Google Incorporated
> *
> * This software is licensed under the terms of the GNU General Public
> @@ -13,10 +13,33 @@
> * GNU General Public License for more details.
> */
>
> -#include "mdp_scale_tables.h"
> +#include <linux/kernel.h>
> +#include <linux/io.h>
> +#include <linux/msm_mdp.h>
> +
> #include "mdp_hw.h"
> +#include "mdp_ppp.h"
> +
> +struct mdp_table_entry {
> + uint32_t reg;
> + uint32_t val;
> +};
> +
> +enum {
> + MDP_DOWNSCALE_PT2TOPT4,
> + MDP_DOWNSCALE_PT4TOPT6,
> + MDP_DOWNSCALE_PT6TOPT8,
> + MDP_DOWNSCALE_PT8TO1,
> + MDP_DOWNSCALE_MAX,
> +
> + /* not technically in the downscale table list */
> + MDP_DOWNSCALE_BLUR,
> +};
>
> -struct mdp_table_entry mdp_upscale_table[] = {
> +static int downscale_x_table;
> +static int downscale_y_table;
> +
> +static struct mdp_table_entry mdp_upscale_table[] = {
> { 0x5fffc, 0x0 },
> { 0x50200, 0x7fc00000 },
> { 0x5fffc, 0xff80000d },
> @@ -764,3 +787,305 @@ struct mdp_table_entry mdp_gaussian_blur_table[] = {
> { 0x5fffc, 0x20000080 },
> { 0x5037c, 0x20000080 },
> };
> +
> +static void load_table(const struct mdp_info *mdp,
> + struct mdp_table_entry *table, int len)
> +{
> + int i;
> + for (i = 0; i < len; i++)
> + mdp_writel(mdp, table[i].val, table[i].reg);
> +}
> +
> +enum {
> + IMG_LEFT,
> + IMG_RIGHT,
> + IMG_TOP,
> + IMG_BOTTOM,
> +};
> +
> +static void get_edge_info(uint32_t src, uint32_t src_coord, uint32_t dst,
> + uint32_t *interp1, uint32_t *interp2,
> + uint32_t *repeat1, uint32_t *repeat2) {
> + if (src > 3 * dst) {
> + *interp1 = 0;
> + *interp2 = src - 1;
> + *repeat1 = 0;
> + *repeat2 = 0;
> + } else if (src == 3 * dst) {
> + *interp1 = 0;
> + *interp2 = src;
> + *repeat1 = 0;
> + *repeat2 = 1;
> + } else if (src > dst && src < 3 * dst) {
> + *interp1 = -1;
> + *interp2 = src;
> + *repeat1 = 1;
> + *repeat2 = 1;
> + } else if (src == dst) {
> + *interp1 = -1;
> + *interp2 = src + 1;
> + *repeat1 = 1;
> + *repeat2 = 2;
> + } else {
> + *interp1 = -2;
> + *interp2 = src + 1;
> + *repeat1 = 2;
> + *repeat2 = 2;
> + }
> + *interp1 += src_coord;
> + *interp2 += src_coord;
> +}
> +
> +int mdp_ppp_cfg_edge_cond(struct mdp_blit_req *req, struct ppp_regs
> *regs)
> +{
> + int32_t luma_interp[4];
> + int32_t luma_repeat[4];
> + int32_t chroma_interp[4];
> + int32_t chroma_bound[4];
> + int32_t chroma_repeat[4];
> + uint32_t dst_w, dst_h;
> +
> + memset(&luma_interp, 0, sizeof(int32_t) * 4);
> + memset(&luma_repeat, 0, sizeof(int32_t) * 4);
> + memset(&chroma_interp, 0, sizeof(int32_t) * 4);
> + memset(&chroma_bound, 0, sizeof(int32_t) * 4);
> + memset(&chroma_repeat, 0, sizeof(int32_t) * 4);
> + regs->edge = 0;
> +
> + if (req->flags & MDP_ROT_90) {
> + dst_w = req->dst_rect.h;
> + dst_h = req->dst_rect.w;
> + } else {
> + dst_w = req->dst_rect.w;
> + dst_h = req->dst_rect.h;
> + }
> +
> + if (regs->op & (PPP_OP_SCALE_Y_ON | PPP_OP_SCALE_X_ON)) {
> + get_edge_info(req->src_rect.h, req->src_rect.y, dst_h,
> + &luma_interp[IMG_TOP], &luma_interp[IMG_BOTTOM],
> + &luma_repeat[IMG_TOP], &luma_repeat[IMG_BOTTOM]);
> + get_edge_info(req->src_rect.w, req->src_rect.x, dst_w,
> + &luma_interp[IMG_LEFT], &luma_interp[IMG_RIGHT],
> + &luma_repeat[IMG_LEFT], &luma_repeat[IMG_RIGHT]);
> + } else {
> + luma_interp[IMG_LEFT] = req->src_rect.x;
> + luma_interp[IMG_RIGHT] = req->src_rect.x + req->src_rect.w -
> 1;
> + luma_interp[IMG_TOP] = req->src_rect.y;
> + luma_interp[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h -
> 1;
> + luma_repeat[IMG_LEFT] = 0;
> + luma_repeat[IMG_TOP] = 0;
> + luma_repeat[IMG_RIGHT] = 0;
> + luma_repeat[IMG_BOTTOM] = 0;
> + }
> +
> + chroma_interp[IMG_LEFT] = luma_interp[IMG_LEFT];
> + chroma_interp[IMG_RIGHT] = luma_interp[IMG_RIGHT];
> + chroma_interp[IMG_TOP] = luma_interp[IMG_TOP];
> + chroma_interp[IMG_BOTTOM] = luma_interp[IMG_BOTTOM];
> +
> + chroma_bound[IMG_LEFT] = req->src_rect.x;
> + chroma_bound[IMG_RIGHT] = req->src_rect.x + req->src_rect.w - 1;
> + chroma_bound[IMG_TOP] = req->src_rect.y;
> + chroma_bound[IMG_BOTTOM] = req->src_rect.y + req->src_rect.h - 1;
> +
> + if (IS_YCRCB(req->src.format)) {
> + chroma_interp[IMG_LEFT] = chroma_interp[IMG_LEFT] >> 1;
> + chroma_interp[IMG_RIGHT] = (chroma_interp[IMG_RIGHT] + 1) >>
> 1;
> +
> + chroma_bound[IMG_LEFT] = chroma_bound[IMG_LEFT] >> 1;
> + chroma_bound[IMG_RIGHT] = chroma_bound[IMG_RIGHT] >> 1;
> + }
> +
> + if (req->src.format == MDP_Y_CBCR_H2V2 ||
> + req->src.format == MDP_Y_CRCB_H2V2) {
> + chroma_interp[IMG_TOP] = (chroma_interp[IMG_TOP] - 1) >> 1;
> + chroma_interp[IMG_BOTTOM] = (chroma_interp[IMG_BOTTOM] + 1)
> + >> 1;
> + chroma_bound[IMG_TOP] = (chroma_bound[IMG_TOP] + 1) >> 1;
> + chroma_bound[IMG_BOTTOM] = chroma_bound[IMG_BOTTOM] >> 1;
> + }
> +
> + chroma_repeat[IMG_LEFT] = chroma_bound[IMG_LEFT] -
> + chroma_interp[IMG_LEFT];
> + chroma_repeat[IMG_RIGHT] = chroma_interp[IMG_RIGHT] -
> + chroma_bound[IMG_RIGHT];
> + chroma_repeat[IMG_TOP] = chroma_bound[IMG_TOP] -
> + chroma_interp[IMG_TOP];
> + chroma_repeat[IMG_BOTTOM] = chroma_interp[IMG_BOTTOM] -
> + chroma_bound[IMG_BOTTOM];
> +
> + if (chroma_repeat[IMG_LEFT] < 0 || chroma_repeat[IMG_LEFT] > 3 ||
> + chroma_repeat[IMG_RIGHT] < 0 || chroma_repeat[IMG_RIGHT] > 3 ||
> + chroma_repeat[IMG_TOP] < 0 || chroma_repeat[IMG_TOP] > 3 ||
> + chroma_repeat[IMG_BOTTOM] < 0 || chroma_repeat[IMG_BOTTOM] > 3
> ||
> + luma_repeat[IMG_LEFT] < 0 || luma_repeat[IMG_LEFT] > 3 ||
> + luma_repeat[IMG_RIGHT] < 0 || luma_repeat[IMG_RIGHT] > 3 ||
> + luma_repeat[IMG_TOP] < 0 || luma_repeat[IMG_TOP] > 3 ||
> + luma_repeat[IMG_BOTTOM] < 0 || luma_repeat[IMG_BOTTOM] > 3)
> + return -1;
Please use error codes defined by linux-kernel.
Please refer to:
http://lxr.linux.no/#linux+v2.6.38/include/asm-generic/errno-base.h
Here you can use -EINVAL for invalid value.
> +
> + regs->edge |= (chroma_repeat[IMG_LEFT] & 3) << MDP_LEFT_CHROMA;
> + regs->edge |= (chroma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_CHROMA;
> + regs->edge |= (chroma_repeat[IMG_TOP] & 3) << MDP_TOP_CHROMA;
> + regs->edge |= (chroma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_CHROMA;
> + regs->edge |= (luma_repeat[IMG_LEFT] & 3) << MDP_LEFT_LUMA;
> + regs->edge |= (luma_repeat[IMG_RIGHT] & 3) << MDP_RIGHT_LUMA;
> + regs->edge |= (luma_repeat[IMG_TOP] & 3) << MDP_TOP_LUMA;
> + regs->edge |= (luma_repeat[IMG_BOTTOM] & 3) << MDP_BOTTOM_LUMA;
> + return 0;
> +}
> +
> +#define ONE_HALF (1LL << 32)
> +#define ONE (1LL << 33)
> +#define TWO (2LL << 33)
> +#define THREE (3LL << 33)
> +#define FRAC_MASK (ONE - 1)
> +#define INT_MASK (~FRAC_MASK)
> +
> +static int scale_params(uint32_t dim_in, uint32_t dim_out, uint32_t
> origin,
> + uint32_t *phase_init, uint32_t *phase_step)
> +{
> + /* to improve precicsion calculations are done in U31.33 and
> converted
> + * to U3.29 at the end */
[cosmetic comment]: Multiline comments?
> + int64_t k1, k2, k3, k4, tmp;
> + uint64_t n, d, os, os_p, od, od_p, oreq;
> + unsigned rpa = 0;
> + int64_t ip64, delta;
> +
> + if (dim_out % 3 == 0)
> + rpa = !(dim_in % (dim_out / 3));
> +
> + n = ((uint64_t)dim_out) << 34;
> + d = dim_in;
> + if (!d)
> + return -1;
Please use standard error codes.
> + do_div(n, d);
> + k3 = (n + 1) >> 1;
> + if ((k3 >> 4) < (1LL << 27) || (k3 >> 4) > (1LL << 31))
> + return -1;
> +
> + n = ((uint64_t)dim_in) << 34;
> + d = (uint64_t)dim_out;
> + if (!d)
> + return -1;
Same: Please use standard error codes.
> + do_div(n, d);
> + k1 = (n + 1) >> 1;
> + k2 = (k1 - ONE) >> 1;
> +
> + *phase_init = (int)(k2 >> 4);
> + k4 = (k3 - ONE) >> 1;
> +
> + if (rpa) {
> + os = ((uint64_t)origin << 33) - ONE_HALF;
> + tmp = (dim_out * os) + ONE_HALF;
> + if (!dim_in)
> + return -1;
> + do_div(tmp, dim_in);
> + od = tmp - ONE_HALF;
> + } else {
> + os = ((uint64_t)origin << 1) - 1;
> + od = (((k3 * os) >> 1) + k4);
> + }
> +
> + od_p = od & INT_MASK;
> + if (od_p != od)
> + od_p += ONE;
> +
> + if (rpa) {
> + tmp = (dim_in * od_p) + ONE_HALF;
> + if (!dim_in)
> + return -1;
> + do_div(tmp, dim_in);
> + os_p = tmp - ONE_HALF;
> + } else {
> + os_p = ((k1 * (od_p >> 33)) + k2);
> + }
> +
> + oreq = (os_p & INT_MASK) - ONE;
> +
> + ip64 = os_p - oreq;
> + delta = ((int64_t)(origin) << 33) - oreq;
> + ip64 -= delta;
> + /* limit to valid range before the left shift */
> + delta = (ip64 & (1LL << 63)) ? 4 : -4;
> + delta <<= 33;
> + while (abs((int)(ip64 >> 33)) > 4)
> + ip64 += delta;
> + *phase_init = (int)(ip64 >> 4);
> + *phase_step = (uint32_t)(k1 >> 4);
> + return 0;
> +}
> +
> +int mdp_ppp_cfg_scale(const struct mdp_info *mdp, struct ppp_regs *regs,
> + struct mdp_rect *src_rect, struct mdp_rect *dst_rect,
> + uint32_t src_format, uint32_t dst_format)
> +{
> + int downscale;
> + uint32_t phase_init_x, phase_init_y, phase_step_x, phase_step_y;
> + uint32_t scale_factor_x, scale_factor_y;
> +
> + if (scale_params(src_rect->w, dst_rect->w, 1, &phase_init_x,
> + &phase_step_x) ||
> + scale_params(src_rect->h, dst_rect->h, 1, &phase_init_y,
> + &phase_step_y))
> + return -1;
Error code?
> +
> + regs->phasex_init = phase_init_x;
> + regs->phasey_init = phase_init_y;
> + regs->phasex_step = phase_step_x;
> + regs->phasey_step = phase_step_y;
> +
> + scale_factor_x = (dst_rect->w * 10) / src_rect->w;
> + scale_factor_y = (dst_rect->h * 10) / src_rect->h;
> +
> + if (scale_factor_x > 8)
> + downscale = MDP_DOWNSCALE_PT8TO1;
> + else if (scale_factor_x > 6)
> + downscale = MDP_DOWNSCALE_PT6TOPT8;
> + else if (scale_factor_x > 4)
> + downscale = MDP_DOWNSCALE_PT4TOPT6;
> + else
> + downscale = MDP_DOWNSCALE_PT2TOPT4;
> +
> + if (downscale != downscale_x_table) {
> + load_table(mdp, mdp_downscale_x_table[downscale], 64);
> + downscale_x_table = downscale;
> + }
> +
> + if (scale_factor_y > 8)
> + downscale = MDP_DOWNSCALE_PT8TO1;
> + else if (scale_factor_y > 6)
> + downscale = MDP_DOWNSCALE_PT6TOPT8;
> + else if (scale_factor_y > 4)
> + downscale = MDP_DOWNSCALE_PT4TOPT6;
> + else
> + downscale = MDP_DOWNSCALE_PT2TOPT4;
> +
> + if (downscale != downscale_y_table) {
> + load_table(mdp, mdp_downscale_y_table[downscale], 64);
> + downscale_y_table = downscale;
> + }
> +
> + return 0;
> +}
> +
> +
[cosmetic comment]: Extra line?
> +int mdp_ppp_load_blur(const struct mdp_info *mdp)
> +{
> + if (!(downscale_x_table == MDP_DOWNSCALE_BLUR &&
> + downscale_y_table == MDP_DOWNSCALE_BLUR)) {
> + load_table(mdp, mdp_gaussian_blur_table, 128);
> + downscale_x_table = MDP_DOWNSCALE_BLUR;
> + downscale_y_table = MDP_DOWNSCALE_BLUR;
> + }
> +
> + return 0;
> +}
> +
> +void mdp_ppp_init_scale(const struct mdp_info *mdp)
> +{
> + downscale_x_table = MDP_DOWNSCALE_MAX;
> + downscale_y_table = MDP_DOWNSCALE_MAX;
> +
> + load_table(mdp, mdp_upscale_table, ARRAY_SIZE(mdp_upscale_table));
> +}
> diff --git a/drivers/video/msm/mdp_scale_tables.h
> b/drivers/video/msm/mdp_scale_tables.h
> deleted file mode 100644
> index 34077b1..0000000
> --- a/drivers/video/msm/mdp_scale_tables.h
> +++ /dev/null
> @@ -1,38 +0,0 @@
> -/* drivers/video/msm_fb/mdp_scale_tables.h
> - *
> - * Copyright (C) 2007 QUALCOMM Incorporated
> - * Copyright (C) 2007 Google Incorporated
> - *
> - * This software is licensed under the terms of the GNU General Public
> - * License version 2, as published by the Free Software Foundation, and
> - * may be copied, distributed, and modified under those terms.
> - *
> - * This program is distributed in the hope that it will be useful,
> - * but WITHOUT ANY WARRANTY; without even the implied warranty of
> - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
> - * GNU General Public License for more details.
> - */
> -#ifndef _MDP_SCALE_TABLES_H_
> -#define _MDP_SCALE_TABLES_H_
> -
> -#include <linux/types.h>
> -struct mdp_table_entry {
> - uint32_t reg;
> - uint32_t val;
> -};
> -
> -extern struct mdp_table_entry mdp_upscale_table[64];
> -
> -enum {
> - MDP_DOWNSCALE_PT2TOPT4,
> - MDP_DOWNSCALE_PT4TOPT6,
> - MDP_DOWNSCALE_PT6TOPT8,
> - MDP_DOWNSCALE_PT8TO1,
> - MDP_DOWNSCALE_MAX,
> -};
> -
> -extern struct mdp_table_entry *mdp_downscale_x_table[MDP_DOWNSCALE_MAX];
> -extern struct mdp_table_entry *mdp_downscale_y_table[MDP_DOWNSCALE_MAX];
> -extern struct mdp_table_entry mdp_gaussian_blur_table[];
> -
> -#endif
> --
> Sent by an employee of the Qualcomm Innovation Center, Inc.
> The Qualcomm Innovation Center, Inc. is a member of the Code Aurora Forum.
>
> --
> To unsubscribe from this list: send the line "unsubscribe linux-fbdev" in
> the body of a message to majordomo at vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
More information about the linux-arm-kernel
mailing list