[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, &regs);
>       get_chroma_addr(&req->src, &req->src_rect, regs.src0, regs.src_bpp,
>                       regs.src_cfg, &regs.src1, &regs.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, &regs);
>       get_chroma_addr(&req->dst, &req->dst_rect, regs.dst0, regs.dst_bpp,
>                       regs.dst_cfg, &regs.dst1, &regs.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, &regs))
> -             return -EINVAL;
>
> +#ifdef CONFIG_MSM_MDP22
> +     if (mdp_ppp_cfg_edge_cond(req, &regs))
> +             return -EINVAL;
> +#endif
>       send_blit(mdp, req, &regs, 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