drm/tegra: plane: Support horizontal reflection
Support horizontal reflection mode which will allow to support 180° rotation mode when combined with the vertical reflection. Signed-off-by: Dmitry Osipenko <digetx@gmail.com> Signed-off-by: Thierry Reding <treding@nvidia.com>
Tento commit je obsažen v:

odevzdal
Thierry Reding

rodič
e9e476f7f7
revize
cd740777d2
@@ -368,6 +368,12 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
|
||||
h_size = window->src.w * bpp;
|
||||
v_size = window->src.h;
|
||||
|
||||
if (window->reflect_x)
|
||||
h_offset += (window->src.w - 1) * bpp;
|
||||
|
||||
if (window->reflect_y)
|
||||
v_offset += window->src.h - 1;
|
||||
|
||||
value = V_PRESCALED_SIZE(v_size) | H_PRESCALED_SIZE(h_size);
|
||||
tegra_plane_writel(plane, value, DC_WIN_PRESCALED_SIZE);
|
||||
|
||||
@@ -404,9 +410,6 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
|
||||
tegra_plane_writel(plane, window->stride[0], DC_WIN_LINE_STRIDE);
|
||||
}
|
||||
|
||||
if (window->reflect_y)
|
||||
v_offset += window->src.h - 1;
|
||||
|
||||
tegra_plane_writel(plane, h_offset, DC_WINBUF_ADDR_H_OFFSET);
|
||||
tegra_plane_writel(plane, v_offset, DC_WINBUF_ADDR_V_OFFSET);
|
||||
|
||||
@@ -470,6 +473,9 @@ static void tegra_dc_setup_window(struct tegra_plane *plane,
|
||||
value |= COLOR_EXPAND;
|
||||
}
|
||||
|
||||
if (window->reflect_x)
|
||||
value |= H_DIRECTION;
|
||||
|
||||
if (window->reflect_y)
|
||||
value |= V_DIRECTION;
|
||||
|
||||
@@ -601,7 +607,10 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
|
||||
struct drm_plane_state *state)
|
||||
{
|
||||
struct tegra_plane_state *plane_state = to_tegra_plane_state(state);
|
||||
unsigned int rotation = DRM_MODE_ROTATE_0 | DRM_MODE_REFLECT_Y;
|
||||
unsigned int supported_rotation = DRM_MODE_ROTATE_0 |
|
||||
DRM_MODE_REFLECT_X |
|
||||
DRM_MODE_REFLECT_Y;
|
||||
unsigned int rotation = state->rotation;
|
||||
struct tegra_bo_tiling *tiling = &plane_state->tiling;
|
||||
struct tegra_plane *tegra = to_tegra_plane(plane);
|
||||
struct tegra_dc *dc = to_tegra_dc(state->crtc);
|
||||
@@ -639,7 +648,21 @@ static int tegra_plane_atomic_check(struct drm_plane *plane,
|
||||
return -EINVAL;
|
||||
}
|
||||
|
||||
rotation = drm_rotation_simplify(state->rotation, rotation);
|
||||
/*
|
||||
* Older userspace used custom BO flag in order to specify the Y
|
||||
* reflection, while modern userspace uses the generic DRM rotation
|
||||
* property in order to achieve the same result. The legacy BO flag
|
||||
* duplicates the DRM rotation property when both are set.
|
||||
*/
|
||||
if (tegra_fb_is_bottom_up(state->fb))
|
||||
rotation |= DRM_MODE_REFLECT_Y;
|
||||
|
||||
rotation = drm_rotation_simplify(rotation, supported_rotation);
|
||||
|
||||
if (rotation & DRM_MODE_REFLECT_X)
|
||||
plane_state->reflect_x = true;
|
||||
else
|
||||
plane_state->reflect_x = false;
|
||||
|
||||
if (rotation & DRM_MODE_REFLECT_Y)
|
||||
plane_state->reflect_y = true;
|
||||
@@ -706,7 +729,8 @@ static void tegra_plane_atomic_update(struct drm_plane *plane,
|
||||
window.dst.w = drm_rect_width(&plane->state->dst);
|
||||
window.dst.h = drm_rect_height(&plane->state->dst);
|
||||
window.bits_per_pixel = fb->format->cpp[0] * 8;
|
||||
window.reflect_y = tegra_fb_is_bottom_up(fb) || state->reflect_y;
|
||||
window.reflect_x = state->reflect_x;
|
||||
window.reflect_y = state->reflect_y;
|
||||
|
||||
/* copy from state */
|
||||
window.zpos = plane->state->normalized_zpos;
|
||||
@@ -792,6 +816,7 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
|
||||
err = drm_plane_create_rotation_property(&plane->base,
|
||||
DRM_MODE_ROTATE_0,
|
||||
DRM_MODE_ROTATE_0 |
|
||||
DRM_MODE_REFLECT_X |
|
||||
DRM_MODE_REFLECT_Y);
|
||||
if (err < 0)
|
||||
dev_err(dc->dev, "failed to create rotation property: %d\n",
|
||||
@@ -1080,6 +1105,7 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
|
||||
err = drm_plane_create_rotation_property(&plane->base,
|
||||
DRM_MODE_ROTATE_0,
|
||||
DRM_MODE_ROTATE_0 |
|
||||
DRM_MODE_REFLECT_X |
|
||||
DRM_MODE_REFLECT_Y);
|
||||
if (err < 0)
|
||||
dev_err(dc->dev, "failed to create rotation property: %d\n",
|
||||
|
Odkázat v novém úkolu
Zablokovat Uživatele