Commit b5bae71a authored by Russell King's avatar Russell King

drm/armada: push interlace calculation into armada_drm_plane_calc()

Push the interlaced frame calculation down into armada_drm_plane_calc()
which needs to apply the same correction for both the overlay and
primary planes.
Signed-off-by: default avatarRussell King <rmk+kernel@armlinux.org.uk>
parent 4aafe00e
...@@ -131,21 +131,21 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane, ...@@ -131,21 +131,21 @@ static void armada_drm_overlay_plane_atomic_update(struct drm_plane *plane,
old_state->fb != state->fb) { old_state->fb != state->fb) {
const struct drm_format_info *format; const struct drm_format_info *format;
u16 src_x, pitches[3]; u16 src_x, pitches[3];
u32 addrs[3]; u32 addrs[2][3];
armada_drm_plane_calc(state, addrs, pitches); armada_drm_plane_calc(state, addrs, pitches, false);
armada_reg_queue_set(regs, idx, addrs[0], armada_reg_queue_set(regs, idx, addrs[0][0],
LCD_SPU_DMA_START_ADDR_Y0); LCD_SPU_DMA_START_ADDR_Y0);
armada_reg_queue_set(regs, idx, addrs[1], armada_reg_queue_set(regs, idx, addrs[0][1],
LCD_SPU_DMA_START_ADDR_U0); LCD_SPU_DMA_START_ADDR_U0);
armada_reg_queue_set(regs, idx, addrs[2], armada_reg_queue_set(regs, idx, addrs[0][2],
LCD_SPU_DMA_START_ADDR_V0); LCD_SPU_DMA_START_ADDR_V0);
armada_reg_queue_set(regs, idx, addrs[0], armada_reg_queue_set(regs, idx, addrs[1][0],
LCD_SPU_DMA_START_ADDR_Y1); LCD_SPU_DMA_START_ADDR_Y1);
armada_reg_queue_set(regs, idx, addrs[1], armada_reg_queue_set(regs, idx, addrs[1][1],
LCD_SPU_DMA_START_ADDR_U1); LCD_SPU_DMA_START_ADDR_U1);
armada_reg_queue_set(regs, idx, addrs[2], armada_reg_queue_set(regs, idx, addrs[1][2],
LCD_SPU_DMA_START_ADDR_V1); LCD_SPU_DMA_START_ADDR_V1);
val = pitches[0] << 16 | pitches[0]; val = pitches[0] << 16 | pitches[0];
......
...@@ -35,8 +35,8 @@ static const uint32_t armada_primary_formats[] = { ...@@ -35,8 +35,8 @@ static const uint32_t armada_primary_formats[] = {
DRM_FORMAT_BGR565, DRM_FORMAT_BGR565,
}; };
void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[3], void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[2][3],
u16 pitches[3]) u16 pitches[3], bool interlaced)
{ {
struct drm_framebuffer *fb = state->fb; struct drm_framebuffer *fb = state->fb;
const struct drm_format_info *format = fb->format; const struct drm_format_info *format = fb->format;
...@@ -52,43 +52,45 @@ void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[3], ...@@ -52,43 +52,45 @@ void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[3],
if (num_planes > 3) if (num_planes > 3)
num_planes = 3; num_planes = 3;
addrs[0] = addr + fb->offsets[0] + y * fb->pitches[0] + addrs[0][0] = addr + fb->offsets[0] + y * fb->pitches[0] +
x * format->cpp[0]; x * format->cpp[0];
pitches[0] = fb->pitches[0]; pitches[0] = fb->pitches[0];
y /= format->vsub; y /= format->vsub;
x /= format->hsub; x /= format->hsub;
for (i = 1; i < num_planes; i++) { for (i = 1; i < num_planes; i++) {
addrs[i] = addr + fb->offsets[i] + y * fb->pitches[i] + addrs[0][i] = addr + fb->offsets[i] + y * fb->pitches[i] +
x * format->cpp[i]; x * format->cpp[i];
pitches[i] = fb->pitches[i]; pitches[i] = fb->pitches[i];
} }
for (; i < 3; i++) { for (; i < 3; i++) {
addrs[i] = 0; addrs[0][i] = 0;
pitches[i] = 0; pitches[i] = 0;
} }
if (interlaced) {
for (i = 0; i < 3; i++) {
addrs[1][i] = addrs[0][i] + pitches[i];
pitches[i] *= 2;
}
} else {
for (i = 0; i < 3; i++)
addrs[1][i] = addrs[0][i];
}
} }
static unsigned armada_drm_crtc_calc_fb(struct drm_plane_state *state, static unsigned armada_drm_crtc_calc_fb(struct drm_plane_state *state,
struct armada_regs *regs, bool interlaced) struct armada_regs *regs, bool interlaced)
{ {
u16 pitches[3]; u16 pitches[3];
u32 addrs[3], addr_odd, addr_even; u32 addrs[2][3];
unsigned i = 0; unsigned i = 0;
armada_drm_plane_calc(state, addrs, pitches); armada_drm_plane_calc(state, addrs, pitches, interlaced);
addr_odd = addr_even = addrs[0];
if (interlaced) {
addr_even += pitches[0];
pitches[0] *= 2;
}
/* write offset, base, and pitch */ /* write offset, base, and pitch */
armada_reg_queue_set(regs, i, addr_odd, LCD_CFG_GRA_START_ADDR0); armada_reg_queue_set(regs, i, addrs[0][0], LCD_CFG_GRA_START_ADDR0);
armada_reg_queue_set(regs, i, addr_even, LCD_CFG_GRA_START_ADDR1); armada_reg_queue_set(regs, i, addrs[1][0], LCD_CFG_GRA_START_ADDR1);
armada_reg_queue_mod(regs, i, pitches[0], 0xffff, LCD_CFG_GRA_PITCH); armada_reg_queue_mod(regs, i, pitches[0], 0xffff, LCD_CFG_GRA_PITCH);
return i; return i;
......
#ifndef ARMADA_PLANE_H #ifndef ARMADA_PLANE_H
#define ARMADA_PLANE_H #define ARMADA_PLANE_H
void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[3], void armada_drm_plane_calc(struct drm_plane_state *state, u32 addrs[2][3],
u16 pitches[3]); u16 pitches[3], bool interlaced);
int armada_drm_plane_prepare_fb(struct drm_plane *plane, int armada_drm_plane_prepare_fb(struct drm_plane *plane,
struct drm_plane_state *state); struct drm_plane_state *state);
void armada_drm_plane_cleanup_fb(struct drm_plane *plane, void armada_drm_plane_cleanup_fb(struct drm_plane *plane,
......
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