|
@@ -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;
|