Commit 0114f404 authored by Marek Szyprowski's avatar Marek Szyprowski Committed by Inki Dae

drm/exynos: introduce exynos_drm_plane_state structure

This patch introduces exynos_drm_plane_state structure, which subclasses
drm_plane_state and holds precalculated data suitable for configuring
Exynos hardware.
Signed-off-by: default avatarMarek Szyprowski <m.szyprowski@samsung.com>
Reviewed-by: default avatarGustavo Padovan <gustavo.padovan@collabora.co.uk>
Signed-off-by: default avatarInki Dae <inki.dae@samsung.com>
parent 0488f50e
...@@ -260,9 +260,10 @@ static void decon_atomic_begin(struct exynos_drm_crtc *crtc, ...@@ -260,9 +260,10 @@ static void decon_atomic_begin(struct exynos_drm_crtc *crtc,
static void decon_update_plane(struct exynos_drm_crtc *crtc, static void decon_update_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane) struct exynos_drm_plane *plane)
{ {
struct exynos_drm_plane_state *state =
to_exynos_plane_state(plane->base.state);
struct decon_context *ctx = crtc->ctx; struct decon_context *ctx = crtc->ctx;
struct drm_plane_state *state = plane->base.state; struct drm_framebuffer *fb = state->base.fb;
struct drm_framebuffer *fb = state->fb;
unsigned int win = plane->zpos; unsigned int win = plane->zpos;
unsigned int bpp = fb->bits_per_pixel >> 3; unsigned int bpp = fb->bits_per_pixel >> 3;
unsigned int pitch = fb->pitches[0]; unsigned int pitch = fb->pitches[0];
...@@ -272,11 +273,11 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, ...@@ -272,11 +273,11 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
if (test_bit(BIT_SUSPENDED, &ctx->flags)) if (test_bit(BIT_SUSPENDED, &ctx->flags))
return; return;
val = COORDINATE_X(plane->crtc_x) | COORDINATE_Y(plane->crtc_y); val = COORDINATE_X(state->crtc.x) | COORDINATE_Y(state->crtc.y);
writel(val, ctx->addr + DECON_VIDOSDxA(win)); writel(val, ctx->addr + DECON_VIDOSDxA(win));
val = COORDINATE_X(plane->crtc_x + plane->crtc_w - 1) | val = COORDINATE_X(state->crtc.x + state->crtc.w - 1) |
COORDINATE_Y(plane->crtc_y + plane->crtc_h - 1); COORDINATE_Y(state->crtc.y + state->crtc.h - 1);
writel(val, ctx->addr + DECON_VIDOSDxB(win)); writel(val, ctx->addr + DECON_VIDOSDxB(win));
val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) | val = VIDOSD_Wx_ALPHA_R_F(0x0) | VIDOSD_Wx_ALPHA_G_F(0x0) |
...@@ -289,15 +290,15 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, ...@@ -289,15 +290,15 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win)); writel(dma_addr, ctx->addr + DECON_VIDW0xADD0B0(win));
val = dma_addr + pitch * plane->crtc_h; val = dma_addr + pitch * state->src.h;
writel(val, ctx->addr + DECON_VIDW0xADD1B0(win)); writel(val, ctx->addr + DECON_VIDW0xADD1B0(win));
if (ctx->out_type != IFTYPE_HDMI) if (ctx->out_type != IFTYPE_HDMI)
val = BIT_VAL(pitch - plane->crtc_w * bpp, 27, 14) val = BIT_VAL(pitch - state->crtc.w * bpp, 27, 14)
| BIT_VAL(plane->crtc_w * bpp, 13, 0); | BIT_VAL(state->crtc.w * bpp, 13, 0);
else else
val = BIT_VAL(pitch - plane->crtc_w * bpp, 29, 15) val = BIT_VAL(pitch - state->crtc.w * bpp, 29, 15)
| BIT_VAL(plane->crtc_w * bpp, 14, 0); | BIT_VAL(state->crtc.w * bpp, 14, 0);
writel(val, ctx->addr + DECON_VIDW0xADD2(win)); writel(val, ctx->addr + DECON_VIDW0xADD2(win));
decon_win_set_pixfmt(ctx, win, fb); decon_win_set_pixfmt(ctx, win, fb);
......
...@@ -394,9 +394,10 @@ static void decon_atomic_begin(struct exynos_drm_crtc *crtc, ...@@ -394,9 +394,10 @@ static void decon_atomic_begin(struct exynos_drm_crtc *crtc,
static void decon_update_plane(struct exynos_drm_crtc *crtc, static void decon_update_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane) struct exynos_drm_plane *plane)
{ {
struct exynos_drm_plane_state *state =
to_exynos_plane_state(plane->base.state);
struct decon_context *ctx = crtc->ctx; struct decon_context *ctx = crtc->ctx;
struct drm_plane_state *state = plane->base.state; struct drm_framebuffer *fb = state->base.fb;
struct drm_framebuffer *fb = state->fb;
int padding; int padding;
unsigned long val, alpha; unsigned long val, alpha;
unsigned int last_x; unsigned int last_x;
...@@ -429,22 +430,22 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, ...@@ -429,22 +430,22 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
writel(fb->height, ctx->regs + VIDW_WHOLE_Y(win)); writel(fb->height, ctx->regs + VIDW_WHOLE_Y(win));
/* offset from the start of the buffer to read */ /* offset from the start of the buffer to read */
writel(plane->src_x, ctx->regs + VIDW_OFFSET_X(win)); writel(state->src.x, ctx->regs + VIDW_OFFSET_X(win));
writel(plane->src_y, ctx->regs + VIDW_OFFSET_Y(win)); writel(state->src.y, ctx->regs + VIDW_OFFSET_Y(win));
DRM_DEBUG_KMS("start addr = 0x%lx\n", DRM_DEBUG_KMS("start addr = 0x%lx\n",
(unsigned long)val); (unsigned long)val);
DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
plane->crtc_w, plane->crtc_h); state->crtc.w, state->crtc.h);
val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) | val = VIDOSDxA_TOPLEFT_X(state->crtc.x) |
VIDOSDxA_TOPLEFT_Y(plane->crtc_y); VIDOSDxA_TOPLEFT_Y(state->crtc.y);
writel(val, ctx->regs + VIDOSD_A(win)); writel(val, ctx->regs + VIDOSD_A(win));
last_x = plane->crtc_x + plane->crtc_w; last_x = state->crtc.x + state->crtc.w;
if (last_x) if (last_x)
last_x--; last_x--;
last_y = plane->crtc_y + plane->crtc_h; last_y = state->crtc.y + state->crtc.h;
if (last_y) if (last_y)
last_y--; last_y--;
...@@ -453,7 +454,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc, ...@@ -453,7 +454,7 @@ static void decon_update_plane(struct exynos_drm_crtc *crtc,
writel(val, ctx->regs + VIDOSD_B(win)); writel(val, ctx->regs + VIDOSD_B(win));
DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n",
plane->crtc_x, plane->crtc_y, last_x, last_y); state->crtc.x, state->crtc.y, last_x, last_y);
/* OSD alpha */ /* OSD alpha */
alpha = VIDOSDxC_ALPHA0_R_F(0x0) | alpha = VIDOSDxC_ALPHA0_R_F(0x0) |
......
...@@ -38,22 +38,44 @@ enum exynos_drm_output_type { ...@@ -38,22 +38,44 @@ enum exynos_drm_output_type {
EXYNOS_DISPLAY_TYPE_VIDI, EXYNOS_DISPLAY_TYPE_VIDI,
}; };
struct exynos_drm_rect {
unsigned int x, y;
unsigned int w, h;
};
/* /*
* Exynos drm common overlay structure. * Exynos drm plane state structure.
* *
* @base: plane object * @base: plane_state object (contains drm_framebuffer pointer)
* @src_x: offset x on a framebuffer to be displayed. * @src: rectangle of the source image data to be displayed (clipped to
* - the unit is screen coordinates. * visible part).
* @src_y: offset y on a framebuffer to be displayed. * @crtc: rectangle of the target image position on hardware screen
* - the unit is screen coordinates. * (clipped to visible part).
* @src_w: width of a partial image to be displayed from framebuffer.
* @src_h: height of a partial image to be displayed from framebuffer.
* @crtc_x: offset x on hardware screen.
* @crtc_y: offset y on hardware screen.
* @crtc_w: window width to be displayed (hardware screen).
* @crtc_h: window height to be displayed (hardware screen).
* @h_ratio: horizontal scaling ratio, 16.16 fixed point * @h_ratio: horizontal scaling ratio, 16.16 fixed point
* @v_ratio: vertical scaling ratio, 16.16 fixed point * @v_ratio: vertical scaling ratio, 16.16 fixed point
*
* this structure consists plane state data that will be applied to hardware
* specific overlay info.
*/
struct exynos_drm_plane_state {
struct drm_plane_state base;
struct exynos_drm_rect crtc;
struct exynos_drm_rect src;
unsigned int h_ratio;
unsigned int v_ratio;
};
static inline struct exynos_drm_plane_state *
to_exynos_plane_state(struct drm_plane_state *state)
{
return container_of(state, struct exynos_drm_plane_state, base);
}
/*
* Exynos drm common overlay structure.
*
* @base: plane object
* @zpos: order of overlay layer(z position). * @zpos: order of overlay layer(z position).
* *
* this structure is common to exynos SoC and its contents would be copied * this structure is common to exynos SoC and its contents would be copied
...@@ -62,16 +84,6 @@ enum exynos_drm_output_type { ...@@ -62,16 +84,6 @@ enum exynos_drm_output_type {
struct exynos_drm_plane { struct exynos_drm_plane {
struct drm_plane base; struct drm_plane base;
unsigned int src_x;
unsigned int src_y;
unsigned int src_w;
unsigned int src_h;
unsigned int crtc_x;
unsigned int crtc_y;
unsigned int crtc_w;
unsigned int crtc_h;
unsigned int h_ratio;
unsigned int v_ratio;
unsigned int zpos; unsigned int zpos;
struct drm_framebuffer *pending_fb; struct drm_framebuffer *pending_fb;
}; };
......
...@@ -641,9 +641,10 @@ static void fimd_atomic_flush(struct exynos_drm_crtc *crtc, ...@@ -641,9 +641,10 @@ static void fimd_atomic_flush(struct exynos_drm_crtc *crtc,
static void fimd_update_plane(struct exynos_drm_crtc *crtc, static void fimd_update_plane(struct exynos_drm_crtc *crtc,
struct exynos_drm_plane *plane) struct exynos_drm_plane *plane)
{ {
struct exynos_drm_plane_state *state =
to_exynos_plane_state(plane->base.state);
struct fimd_context *ctx = crtc->ctx; struct fimd_context *ctx = crtc->ctx;
struct drm_plane_state *state = plane->base.state; struct drm_framebuffer *fb = state->base.fb;
struct drm_framebuffer *fb = state->fb;
dma_addr_t dma_addr; dma_addr_t dma_addr;
unsigned long val, size, offset; unsigned long val, size, offset;
unsigned int last_x, last_y, buf_offsize, line_size; unsigned int last_x, last_y, buf_offsize, line_size;
...@@ -654,8 +655,8 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, ...@@ -654,8 +655,8 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
if (ctx->suspended) if (ctx->suspended)
return; return;
offset = plane->src_x * bpp; offset = state->src.x * bpp;
offset += plane->src_y * pitch; offset += state->src.y * pitch;
/* buffer start address */ /* buffer start address */
dma_addr = exynos_drm_fb_dma_addr(fb, 0) + offset; dma_addr = exynos_drm_fb_dma_addr(fb, 0) + offset;
...@@ -663,18 +664,18 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, ...@@ -663,18 +664,18 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
writel(val, ctx->regs + VIDWx_BUF_START(win, 0)); writel(val, ctx->regs + VIDWx_BUF_START(win, 0));
/* buffer end address */ /* buffer end address */
size = pitch * plane->crtc_h; size = pitch * state->crtc.h;
val = (unsigned long)(dma_addr + size); val = (unsigned long)(dma_addr + size);
writel(val, ctx->regs + VIDWx_BUF_END(win, 0)); writel(val, ctx->regs + VIDWx_BUF_END(win, 0));
DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n", DRM_DEBUG_KMS("start addr = 0x%lx, end addr = 0x%lx, size = 0x%lx\n",
(unsigned long)dma_addr, val, size); (unsigned long)dma_addr, val, size);
DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n", DRM_DEBUG_KMS("ovl_width = %d, ovl_height = %d\n",
plane->crtc_w, plane->crtc_h); state->crtc.w, state->crtc.h);
/* buffer size */ /* buffer size */
buf_offsize = pitch - (plane->crtc_w * bpp); buf_offsize = pitch - (state->crtc.w * bpp);
line_size = plane->crtc_w * bpp; line_size = state->crtc.w * bpp;
val = VIDW_BUF_SIZE_OFFSET(buf_offsize) | val = VIDW_BUF_SIZE_OFFSET(buf_offsize) |
VIDW_BUF_SIZE_PAGEWIDTH(line_size) | VIDW_BUF_SIZE_PAGEWIDTH(line_size) |
VIDW_BUF_SIZE_OFFSET_E(buf_offsize) | VIDW_BUF_SIZE_OFFSET_E(buf_offsize) |
...@@ -682,16 +683,16 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, ...@@ -682,16 +683,16 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
writel(val, ctx->regs + VIDWx_BUF_SIZE(win, 0)); writel(val, ctx->regs + VIDWx_BUF_SIZE(win, 0));
/* OSD position */ /* OSD position */
val = VIDOSDxA_TOPLEFT_X(plane->crtc_x) | val = VIDOSDxA_TOPLEFT_X(state->crtc.x) |
VIDOSDxA_TOPLEFT_Y(plane->crtc_y) | VIDOSDxA_TOPLEFT_Y(state->crtc.y) |
VIDOSDxA_TOPLEFT_X_E(plane->crtc_x) | VIDOSDxA_TOPLEFT_X_E(state->crtc.x) |
VIDOSDxA_TOPLEFT_Y_E(plane->crtc_y); VIDOSDxA_TOPLEFT_Y_E(state->crtc.y);
writel(val, ctx->regs + VIDOSD_A(win)); writel(val, ctx->regs + VIDOSD_A(win));
last_x = plane->crtc_x + plane->crtc_w; last_x = state->crtc.x + state->crtc.w;
if (last_x) if (last_x)
last_x--; last_x--;
last_y = plane->crtc_y + plane->crtc_h; last_y = state->crtc.y + state->crtc.h;
if (last_y) if (last_y)
last_y--; last_y--;
...@@ -701,14 +702,14 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc, ...@@ -701,14 +702,14 @@ static void fimd_update_plane(struct exynos_drm_crtc *crtc,
writel(val, ctx->regs + VIDOSD_B(win)); writel(val, ctx->regs + VIDOSD_B(win));
DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n", DRM_DEBUG_KMS("osd pos: tx = %d, ty = %d, bx = %d, by = %d\n",
plane->crtc_x, plane->crtc_y, last_x, last_y); state->crtc.x, state->crtc.y, last_x, last_y);
/* OSD size */ /* OSD size */
if (win != 3 && win != 4) { if (win != 3 && win != 4) {
u32 offset = VIDOSD_D(win); u32 offset = VIDOSD_D(win);
if (win == 0) if (win == 0)
offset = VIDOSD_C(win); offset = VIDOSD_C(win);
val = plane->crtc_w * plane->crtc_h; val = state->crtc.w * state->crtc.h;
writel(val, ctx->regs + offset); writel(val, ctx->regs + offset);
DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val); DRM_DEBUG_KMS("osd size = 0x%x\n", (unsigned int)val);
......
...@@ -56,19 +56,35 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last) ...@@ -56,19 +56,35 @@ static int exynos_plane_get_size(int start, unsigned length, unsigned last)
return size; return size;
} }
static void exynos_plane_mode_set(struct drm_plane *plane, static void exynos_plane_mode_set(struct exynos_drm_plane_state *exynos_state)
struct drm_crtc *crtc,
struct drm_framebuffer *fb,
int crtc_x, int crtc_y,
unsigned int crtc_w, unsigned int crtc_h,
uint32_t src_x, uint32_t src_y,
uint32_t src_w, uint32_t src_h)
{ {
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); struct drm_plane_state *state = &exynos_state->base;
struct drm_crtc *crtc = exynos_state->base.crtc;
struct drm_display_mode *mode = &crtc->state->adjusted_mode; struct drm_display_mode *mode = &crtc->state->adjusted_mode;
int crtc_x, crtc_y;
unsigned int crtc_w, crtc_h;
unsigned int src_x, src_y;
unsigned int src_w, src_h;
unsigned int actual_w; unsigned int actual_w;
unsigned int actual_h; unsigned int actual_h;
/*
* The original src/dest coordinates are stored in exynos_state->base,
* but we want to keep another copy internal to our driver that we can
* clip/modify ourselves.
*/
crtc_x = state->crtc_x;
crtc_y = state->crtc_y;
crtc_w = state->crtc_w;
crtc_h = state->crtc_h;
src_x = state->src_x >> 16;
src_y = state->src_y >> 16;
src_w = state->src_w >> 16;
src_h = state->src_h >> 16;
actual_w = exynos_plane_get_size(crtc_x, crtc_w, mode->hdisplay); actual_w = exynos_plane_get_size(crtc_x, crtc_w, mode->hdisplay);
actual_h = exynos_plane_get_size(crtc_y, crtc_h, mode->vdisplay); actual_h = exynos_plane_get_size(crtc_y, crtc_h, mode->vdisplay);
...@@ -85,46 +101,93 @@ static void exynos_plane_mode_set(struct drm_plane *plane, ...@@ -85,46 +101,93 @@ static void exynos_plane_mode_set(struct drm_plane *plane,
} }
/* set ratio */ /* set ratio */
exynos_plane->h_ratio = (src_w << 16) / crtc_w; exynos_state->h_ratio = (src_w << 16) / crtc_w;
exynos_plane->v_ratio = (src_h << 16) / crtc_h; exynos_state->v_ratio = (src_h << 16) / crtc_h;
/* set drm framebuffer data. */ /* set drm framebuffer data. */
exynos_plane->src_x = src_x; exynos_state->src.x = src_x;
exynos_plane->src_y = src_y; exynos_state->src.y = src_y;
exynos_plane->src_w = (actual_w * exynos_plane->h_ratio) >> 16; exynos_state->src.w = (actual_w * exynos_state->h_ratio) >> 16;
exynos_plane->src_h = (actual_h * exynos_plane->v_ratio) >> 16; exynos_state->src.h = (actual_h * exynos_state->v_ratio) >> 16;
/* set plane range to be displayed. */ /* set plane range to be displayed. */
exynos_plane->crtc_x = crtc_x; exynos_state->crtc.x = crtc_x;
exynos_plane->crtc_y = crtc_y; exynos_state->crtc.y = crtc_y;
exynos_plane->crtc_w = actual_w; exynos_state->crtc.w = actual_w;
exynos_plane->crtc_h = actual_h; exynos_state->crtc.h = actual_h;
DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)", DRM_DEBUG_KMS("plane : offset_x/y(%d,%d), width/height(%d,%d)",
exynos_plane->crtc_x, exynos_plane->crtc_y, exynos_state->crtc.x, exynos_state->crtc.y,
exynos_plane->crtc_w, exynos_plane->crtc_h); exynos_state->crtc.w, exynos_state->crtc.h);
}
plane->crtc = crtc; static void exynos_drm_plane_reset(struct drm_plane *plane)
{
struct exynos_drm_plane_state *exynos_state;
if (plane->state) {
exynos_state = to_exynos_plane_state(plane->state);
if (exynos_state->base.fb)
drm_framebuffer_unreference(exynos_state->base.fb);
kfree(exynos_state);
plane->state = NULL;
}
exynos_state = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
if (exynos_state) {
plane->state = &exynos_state->base;
plane->state->plane = plane;
}
}
static struct drm_plane_state *
exynos_drm_plane_duplicate_state(struct drm_plane *plane)
{
struct exynos_drm_plane_state *exynos_state;
struct exynos_drm_plane_state *copy;
exynos_state = to_exynos_plane_state(plane->state);
copy = kzalloc(sizeof(*exynos_state), GFP_KERNEL);
if (!copy)
return NULL;
__drm_atomic_helper_plane_duplicate_state(plane, &copy->base);
return &copy->base;
}
static void exynos_drm_plane_destroy_state(struct drm_plane *plane,
struct drm_plane_state *old_state)
{
struct exynos_drm_plane_state *old_exynos_state =
to_exynos_plane_state(old_state);
__drm_atomic_helper_plane_destroy_state(plane, old_state);
kfree(old_exynos_state);
} }
static struct drm_plane_funcs exynos_plane_funcs = { static struct drm_plane_funcs exynos_plane_funcs = {
.update_plane = drm_atomic_helper_update_plane, .update_plane = drm_atomic_helper_update_plane,
.disable_plane = drm_atomic_helper_disable_plane, .disable_plane = drm_atomic_helper_disable_plane,
.destroy = drm_plane_cleanup, .destroy = drm_plane_cleanup,
.reset = drm_atomic_helper_plane_reset, .reset = exynos_drm_plane_reset,
.atomic_duplicate_state = drm_atomic_helper_plane_duplicate_state, .atomic_duplicate_state = exynos_drm_plane_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_plane_destroy_state, .atomic_destroy_state = exynos_drm_plane_destroy_state,
}; };
static int exynos_plane_atomic_check(struct drm_plane *plane, static int exynos_plane_atomic_check(struct drm_plane *plane,
struct drm_plane_state *state) struct drm_plane_state *state)
{ {
struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane); struct exynos_drm_plane *exynos_plane = to_exynos_plane(plane);
struct exynos_drm_plane_state *exynos_state =
to_exynos_plane_state(state);
int ret = 0;
if (!state->fb) if (!state->crtc || !state->fb)
return 0; return 0;
return 0; /* translate state into exynos_state */
exynos_plane_mode_set(exynos_state);
return ret;
} }
static void exynos_plane_atomic_update(struct drm_plane *plane, static void exynos_plane_atomic_update(struct drm_plane *plane,
...@@ -137,12 +200,7 @@ static void exynos_plane_atomic_update(struct drm_plane *plane, ...@@ -137,12 +200,7 @@ static void exynos_plane_atomic_update(struct drm_plane *plane,
if (!state->crtc) if (!state->crtc)
return; return;
exynos_plane_mode_set(plane, state->crtc, state->fb, plane->crtc = state->crtc;
state->crtc_x, state->crtc_y,
state->crtc_w, state->crtc_h,
state->src_x >> 16, state->src_y >> 16,
state->src_w >> 16, state->src_h >> 16);
exynos_plane->pending_fb = state->fb; exynos_plane->pending_fb = state->fb;
if (exynos_crtc->ops->update_plane) if (exynos_crtc->ops->update_plane)
...@@ -159,8 +217,7 @@ static void exynos_plane_atomic_disable(struct drm_plane *plane, ...@@ -159,8 +217,7 @@ static void exynos_plane_atomic_disable(struct drm_plane *plane,
return; return;
if (exynos_crtc->ops->disable_plane) if (exynos_crtc->ops->disable_plane)
exynos_crtc->ops->disable_plane(exynos_crtc, exynos_crtc->ops->disable_plane(exynos_crtc, exynos_plane);
exynos_plane);
} }
static const struct drm_plane_helper_funcs plane_helper_funcs = { static const struct drm_plane_helper_funcs plane_helper_funcs = {
......
...@@ -400,10 +400,11 @@ static void mixer_stop(struct mixer_context *ctx) ...@@ -400,10 +400,11 @@ static void mixer_stop(struct mixer_context *ctx)
static void vp_video_buffer(struct mixer_context *ctx, static void vp_video_buffer(struct mixer_context *ctx,
struct exynos_drm_plane *plane) struct exynos_drm_plane *plane)
{ {
struct exynos_drm_plane_state *state =
to_exynos_plane_state(plane->base.state);
struct mixer_resources *res = &ctx->mixer_res; struct mixer_resources *res = &ctx->mixer_res;
struct drm_plane_state *state = plane->base.state; struct drm_framebuffer *fb = state->base.fb;
struct drm_framebuffer *fb = state->fb; struct drm_display_mode *mode = &state->base.crtc->mode;
struct drm_display_mode *mode = &state->crtc->mode;
unsigned long flags; unsigned long flags;
dma_addr_t luma_addr[2], chroma_addr[2]; dma_addr_t luma_addr[2], chroma_addr[2];
bool tiled_mode = false; bool tiled_mode = false;
...@@ -460,24 +461,24 @@ static void vp_video_buffer(struct mixer_context *ctx, ...@@ -460,24 +461,24 @@ static void vp_video_buffer(struct mixer_context *ctx,
vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) | vp_reg_write(res, VP_IMG_SIZE_C, VP_IMG_HSIZE(fb->pitches[0]) |
VP_IMG_VSIZE(fb->height / 2)); VP_IMG_VSIZE(fb->height / 2));
vp_reg_write(res, VP_SRC_WIDTH, plane->src_w); vp_reg_write(res, VP_SRC_WIDTH, state->src.w);
vp_reg_write(res, VP_SRC_HEIGHT, plane->src_h); vp_reg_write(res, VP_SRC_HEIGHT, state->src.h);
vp_reg_write(res, VP_SRC_H_POSITION, vp_reg_write(res, VP_SRC_H_POSITION,
VP_SRC_H_POSITION_VAL(plane->src_x)); VP_SRC_H_POSITION_VAL(state->src.x));
vp_reg_write(res, VP_SRC_V_POSITION, plane->src_y); vp_reg_write(res, VP_SRC_V_POSITION, state->src.y);
vp_reg_write(res, VP_DST_WIDTH, plane->crtc_w); vp_reg_write(res, VP_DST_WIDTH, state->crtc.w);
vp_reg_write(res, VP_DST_H_POSITION, plane->crtc_x); vp_reg_write(res, VP_DST_H_POSITION, state->crtc.x);
if (ctx->interlace) { if (ctx->interlace) {
vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_h / 2); vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h / 2);
vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y / 2); vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y / 2);
} else { } else {
vp_reg_write(res, VP_DST_HEIGHT, plane->crtc_h); vp_reg_write(res, VP_DST_HEIGHT, state->crtc.h);
vp_reg_write(res, VP_DST_V_POSITION, plane->crtc_y); vp_reg_write(res, VP_DST_V_POSITION, state->crtc.y);
} }
vp_reg_write(res, VP_H_RATIO, plane->h_ratio); vp_reg_write(res, VP_H_RATIO, state->h_ratio);
vp_reg_write(res, VP_V_RATIO, plane->v_ratio); vp_reg_write(res, VP_V_RATIO, state->v_ratio);
vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE); vp_reg_write(res, VP_ENDIAN_MODE, VP_ENDIAN_MODE_LITTLE);
...@@ -509,15 +510,18 @@ static void mixer_layer_update(struct mixer_context *ctx) ...@@ -509,15 +510,18 @@ static void mixer_layer_update(struct mixer_context *ctx)
static int mixer_setup_scale(const struct exynos_drm_plane *plane, static int mixer_setup_scale(const struct exynos_drm_plane *plane,
unsigned int *x_ratio, unsigned int *y_ratio) unsigned int *x_ratio, unsigned int *y_ratio)
{ {
if (plane->crtc_w != plane->src_w) { struct exynos_drm_plane_state *state =
if (plane->crtc_w == 2 * plane->src_w) to_exynos_plane_state(plane->base.state);
if (state->crtc.w != state->src.w) {
if (state->crtc.w == 2 * state->src.w)
*x_ratio = 1; *x_ratio = 1;
else else
goto fail; goto fail;
} }
if (plane->crtc_h != plane->src_h) { if (state->crtc.h != state->src.h) {
if (plane->crtc_h == 2 * plane->src_h) if (state->crtc.h == 2 * state->src.h)
*y_ratio = 1; *y_ratio = 1;
else else
goto fail; goto fail;
...@@ -533,10 +537,11 @@ static int mixer_setup_scale(const struct exynos_drm_plane *plane, ...@@ -533,10 +537,11 @@ static int mixer_setup_scale(const struct exynos_drm_plane *plane,
static void mixer_graph_buffer(struct mixer_context *ctx, static void mixer_graph_buffer(struct mixer_context *ctx,
struct exynos_drm_plane *plane) struct exynos_drm_plane *plane)
{ {
struct exynos_drm_plane_state *state =
to_exynos_plane_state(plane->base.state);
struct mixer_resources *res = &ctx->mixer_res; struct mixer_resources *res = &ctx->mixer_res;
struct drm_plane_state *state = plane->base.state; struct drm_framebuffer *fb = state->base.fb;
struct drm_framebuffer *fb = state->fb; struct drm_display_mode *mode = &state->base.crtc->mode;
struct drm_display_mode *mode = &state->crtc->mode;
unsigned long flags; unsigned long flags;
unsigned int win = plane->zpos; unsigned int win = plane->zpos;
unsigned int x_ratio = 0, y_ratio = 0; unsigned int x_ratio = 0, y_ratio = 0;
...@@ -572,13 +577,13 @@ static void mixer_graph_buffer(struct mixer_context *ctx, ...@@ -572,13 +577,13 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
if (mixer_setup_scale(plane, &x_ratio, &y_ratio)) if (mixer_setup_scale(plane, &x_ratio, &y_ratio))
return; return;
dst_x_offset = plane->crtc_x; dst_x_offset = state->crtc.x;
dst_y_offset = plane->crtc_y; dst_y_offset = state->crtc.y;
/* converting dma address base and source offset */ /* converting dma address base and source offset */
dma_addr = exynos_drm_fb_dma_addr(fb, 0) dma_addr = exynos_drm_fb_dma_addr(fb, 0)
+ (plane->src_x * fb->bits_per_pixel >> 3) + (state->src.x * fb->bits_per_pixel >> 3)
+ (plane->src_y * fb->pitches[0]); + (state->src.y * fb->pitches[0]);
src_x_offset = 0; src_x_offset = 0;
src_y_offset = 0; src_y_offset = 0;
...@@ -606,8 +611,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx, ...@@ -606,8 +611,8 @@ static void mixer_graph_buffer(struct mixer_context *ctx,
mixer_reg_write(res, MXR_RESOLUTION, val); mixer_reg_write(res, MXR_RESOLUTION, val);
} }
val = MXR_GRP_WH_WIDTH(plane->src_w); val = MXR_GRP_WH_WIDTH(state->src.w);
val |= MXR_GRP_WH_HEIGHT(plane->src_h); val |= MXR_GRP_WH_HEIGHT(state->src.h);
val |= MXR_GRP_WH_H_SCALE(x_ratio); val |= MXR_GRP_WH_H_SCALE(x_ratio);
val |= MXR_GRP_WH_V_SCALE(y_ratio); val |= MXR_GRP_WH_V_SCALE(y_ratio);
mixer_reg_write(res, MXR_GRAPHIC_WH(win), val); mixer_reg_write(res, MXR_GRAPHIC_WH(win), val);
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment