drm/exynos: added vp scaling feature for hdmi
authorSeung-Woo Kim <sw0312.kim@samsung.com>
Tue, 24 Apr 2012 09:52:22 +0000 (18:52 +0900)
committerInki Dae <inki.dae@samsung.com>
Thu, 17 May 2012 11:14:40 +0000 (20:14 +0900)
This patch adds vp scaling feature for exynos hdmi. Scaling ratio
between source and destination is used for width and height.
Also meaningless variables to set registers are cleaned.

Signed-off-by: Seung-Woo Kim <sw0312.kim@samsung.com>
Signed-off-by: Kyungmin Park <kyungmin.park@samsung.com>
Signed-off-by: Inki Dae <inki.dae@samsung.com>
drivers/gpu/drm/exynos/exynos_mixer.c

index 3bc01a6..68ef010 100644 (file)
@@ -54,6 +54,8 @@ struct hdmi_win_data {
        unsigned int            fb_y;
        unsigned int            fb_width;
        unsigned int            fb_height;
+       unsigned int            src_width;
+       unsigned int            src_height;
        unsigned int            mode_width;
        unsigned int            mode_height;
        unsigned int            scan_flags;
@@ -351,10 +353,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
        struct mixer_resources *res = &ctx->mixer_res;
        unsigned long flags;
        struct hdmi_win_data *win_data;
-       unsigned int full_width, full_height, width, height;
        unsigned int x_ratio, y_ratio;
-       unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
-       unsigned int mode_width, mode_height;
        unsigned int buf_num;
        dma_addr_t luma_addr[2], chroma_addr[2];
        bool tiled_mode = false;
@@ -381,21 +380,9 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
                return;
        }
 
-       full_width = win_data->fb_width;
-       full_height = win_data->fb_height;
-       width = win_data->crtc_width;
-       height = win_data->crtc_height;
-       mode_width = win_data->mode_width;
-       mode_height = win_data->mode_height;
-
        /* scaling feature: (src << 16) / dst */
-       x_ratio = (width << 16) / width;
-       y_ratio = (height << 16) / height;
-
-       src_x_offset = win_data->fb_x;
-       src_y_offset = win_data->fb_y;
-       dst_x_offset = win_data->crtc_x;
-       dst_y_offset = win_data->crtc_y;
+       x_ratio = (win_data->src_width << 16) / win_data->crtc_width;
+       y_ratio = (win_data->src_height << 16) / win_data->crtc_height;
 
        if (buf_num == 2) {
                luma_addr[0] = win_data->dma_addr;
@@ -403,7 +390,7 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
        } else {
                luma_addr[0] = win_data->dma_addr;
                chroma_addr[0] = win_data->dma_addr
-                       + (full_width * full_height);
+                       + (win_data->fb_width * win_data->fb_height);
        }
 
        if (win_data->scan_flags & DRM_MODE_FLAG_INTERLACE) {
@@ -412,8 +399,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
                        luma_addr[1] = luma_addr[0] + 0x40;
                        chroma_addr[1] = chroma_addr[0] + 0x40;
                } else {
-                       luma_addr[1] = luma_addr[0] + full_width;
-                       chroma_addr[1] = chroma_addr[0] + full_width;
+                       luma_addr[1] = luma_addr[0] + win_data->fb_width;
+                       chroma_addr[1] = chroma_addr[0] + win_data->fb_width;
                }
        } else {
                ctx->interlace = false;
@@ -434,26 +421,26 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
        vp_reg_writemask(res, VP_MODE, val, VP_MODE_FMT_MASK);
 
        /* setting size of input image */
-       vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(full_width) |
-               VP_IMG_VSIZE(full_height));
+       vp_reg_write(res, VP_IMG_SIZE_Y, VP_IMG_HSIZE(win_data->fb_width) |
+               VP_IMG_VSIZE(win_data->fb_height));
        /* chroma height has to reduced by 2 to avoid chroma distorions */
-       vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(full_width) |
-               VP_IMG_VSIZE(full_height / 2));
+       vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(win_data->fb_width) |
+               VP_IMG_VSIZE(win_data->fb_height / 2));
 
-       vp_reg_write(res, VP_SRC_WIDTH, width);
-       vp_reg_write(res, VP_SRC_HEIGHT, height);
+       vp_reg_write(res, VP_SRC_WIDTH, win_data->src_width);
+       vp_reg_write(res, VP_SRC_HEIGHT, win_data->src_height);
        vp_reg_write(res, VP_SRC_H_POSITION,
-                       VP_SRC_H_POSITION_VAL(src_x_offset));
-       vp_reg_write(res, VP_SRC_V_POSITION, src_y_offset);
+                       VP_SRC_H_POSITION_VAL(win_data->fb_x));
+       vp_reg_write(res, VP_SRC_V_POSITION, win_data->fb_y);
 
-       vp_reg_write(res, VP_DST_WIDTH, width);
-       vp_reg_write(res, VP_DST_H_POSITION, dst_x_offset);
+       vp_reg_write(res, VP_DST_WIDTH, win_data->crtc_width);
+       vp_reg_write(res, VP_DST_H_POSITION, win_data->crtc_x);
        if (ctx->interlace) {
-               vp_reg_write(res, VP_DST_HEIGHT, height / 2);
-               vp_reg_write(res, VP_DST_V_POSITION, dst_y_offset / 2);
+               vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height / 2);
+               vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y / 2);
        } else {
-               vp_reg_write(res, VP_DST_HEIGHT, height);
-               vp_reg_write(res, VP_DST_V_POSITION, dst_y_offset);
+               vp_reg_write(res, VP_DST_HEIGHT, win_data->crtc_height);
+               vp_reg_write(res, VP_DST_V_POSITION, win_data->crtc_y);
        }
 
        vp_reg_write(res, VP_H_RATIO, x_ratio);
@@ -467,8 +454,8 @@ static void vp_video_buffer(struct mixer_context *ctx, int win)
        vp_reg_write(res, VP_TOP_C_PTR, chroma_addr[0]);
        vp_reg_write(res, VP_BOT_C_PTR, chroma_addr[1]);
 
-       mixer_cfg_scan(ctx, mode_height);
-       mixer_cfg_rgb_fmt(ctx, mode_height);
+       mixer_cfg_scan(ctx, win_data->mode_height);
+       mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
        mixer_cfg_layer(ctx, win, true);
        mixer_run(ctx);
 
@@ -483,10 +470,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
        struct mixer_resources *res = &ctx->mixer_res;
        unsigned long flags;
        struct hdmi_win_data *win_data;
-       unsigned int full_width, width, height;
        unsigned int x_ratio, y_ratio;
        unsigned int src_x_offset, src_y_offset, dst_x_offset, dst_y_offset;
-       unsigned int mode_width, mode_height;
        dma_addr_t dma_addr;
        unsigned int fmt;
        u32 val;
@@ -509,26 +494,17 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
                fmt = ARGB8888;
        }
 
-       dma_addr = win_data->dma_addr;
-       full_width = win_data->fb_width;
-       width = win_data->crtc_width;
-       height = win_data->crtc_height;
-       mode_width = win_data->mode_width;
-       mode_height = win_data->mode_height;
-
        /* 2x scaling feature */
        x_ratio = 0;
        y_ratio = 0;
 
-       src_x_offset = win_data->fb_x;
-       src_y_offset = win_data->fb_y;
        dst_x_offset = win_data->crtc_x;
        dst_y_offset = win_data->crtc_y;
 
        /* converting dma address base and source offset */
-       dma_addr = dma_addr
-               + (src_x_offset * win_data->bpp >> 3)
-               + (src_y_offset * full_width * win_data->bpp >> 3);
+       dma_addr = win_data->dma_addr
+               + (win_data->fb_x * win_data->bpp >> 3)
+               + (win_data->fb_y * win_data->fb_width * win_data->bpp >> 3);
        src_x_offset = 0;
        src_y_offset = 0;
 
@@ -545,10 +521,10 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
                MXR_GRP_CFG_FORMAT_VAL(fmt), MXR_GRP_CFG_FORMAT_MASK);
 
        /* setup geometry */
-       mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), full_width);
+       mixer_reg_write(res, MXR_GRAPHIC_SPAN(win), win_data->fb_width);
 
-       val  = MXR_GRP_WH_WIDTH(width);
-       val |= MXR_GRP_WH_HEIGHT(height);
+       val  = MXR_GRP_WH_WIDTH(win_data->crtc_width);
+       val |= MXR_GRP_WH_HEIGHT(win_data->crtc_height);
        val |= MXR_GRP_WH_H_SCALE(x_ratio);
        val |= MXR_GRP_WH_V_SCALE(y_ratio);
        mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
@@ -566,8 +542,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, int win)
        /* set buffer address to mixer */
        mixer_reg_write(res, MXR_GRAPHIC_BASE(win), dma_addr);
 
-       mixer_cfg_scan(ctx, mode_height);
-       mixer_cfg_rgb_fmt(ctx, mode_height);
+       mixer_cfg_scan(ctx, win_data->mode_height);
+       mixer_cfg_rgb_fmt(ctx, win_data->mode_height);
        mixer_cfg_layer(ctx, win, true);
        mixer_run(ctx);
 
@@ -795,6 +771,8 @@ static void mixer_win_mode_set(void *ctx,
        win_data->fb_y = overlay->fb_y;
        win_data->fb_width = overlay->fb_width;
        win_data->fb_height = overlay->fb_height;
+       win_data->src_width = overlay->src_width;
+       win_data->src_height = overlay->src_height;
 
        win_data->mode_width = overlay->mode_width;
        win_data->mode_height = overlay->mode_height;