mirror of
git://nv-tegra.nvidia.com/linux-nv-oot.git
synced 2025-12-22 17:25:35 +03:00
drm/tegra: Support asynchronous commits for cursor
This adds support for asynchronously updating the cursor plane, which enables support for the legacy cursor IOCTLs. Bug 200768479 Signed-off-by: Thierry Reding <treding@nvidia.com> Change-Id: Iaf77883db8de83d36251c686db523ea3d6f0bee1 Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2596400 (cherry picked from commit b8211942c65092e4d28caf8cf63036dce3ed3501) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2620153 Tested-by: Jonathan Hunter <jonathanh@nvidia.com> Tested-by: mobile promotions <svcmobile_promotions@nvidia.com> Reviewed-by: Jonathan Hunter <jonathanh@nvidia.com> Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com> Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com> Reviewed-by: mobile promotions <svcmobile_promotions@nvidia.com> GVS: Gerrit_Virtual_Submit
This commit is contained in:
committed by
Laxman Dewangan
parent
1da27ee38f
commit
cc4ccb187b
@@ -899,17 +899,9 @@ static int tegra_cursor_atomic_check(struct drm_plane *plane,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void tegra_cursor_atomic_update(struct drm_plane *plane,
|
static void __tegra_cursor_atomic_update(struct drm_plane *plane,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
|
struct drm_plane_state *new_state)
|
||||||
struct drm_atomic_state *state)
|
|
||||||
{
|
{
|
||||||
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state,
|
|
||||||
plane);
|
|
||||||
#else
|
|
||||||
struct drm_plane_state *old_state)
|
|
||||||
{
|
|
||||||
struct drm_plane_state *new_state = plane->state;
|
|
||||||
#endif
|
|
||||||
struct tegra_plane_state *tegra_plane_state = to_tegra_plane_state(new_state);
|
struct tegra_plane_state *tegra_plane_state = to_tegra_plane_state(new_state);
|
||||||
struct tegra_dc *dc = to_tegra_dc(new_state->crtc);
|
struct tegra_dc *dc = to_tegra_dc(new_state->crtc);
|
||||||
struct tegra_drm *tegra = plane->dev->dev_private;
|
struct tegra_drm *tegra = plane->dev->dev_private;
|
||||||
@@ -1011,6 +1003,21 @@ static void tegra_cursor_atomic_update(struct drm_plane *plane,
|
|||||||
tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION);
|
tegra_dc_writel(dc, value, DC_DISP_CURSOR_POSITION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
static void tegra_cursor_atomic_update(struct drm_plane *plane,
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
|
||||||
|
struct drm_atomic_state *state)
|
||||||
|
{
|
||||||
|
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
|
||||||
|
#else
|
||||||
|
struct drm_plane_state *old_state)
|
||||||
|
{
|
||||||
|
struct drm_plane_state *new_state = plane->state;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
__tegra_cursor_atomic_update(plane, new_state);
|
||||||
|
}
|
||||||
|
|
||||||
static void tegra_cursor_atomic_disable(struct drm_plane *plane,
|
static void tegra_cursor_atomic_disable(struct drm_plane *plane,
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
|
||||||
struct drm_atomic_state *state)
|
struct drm_atomic_state *state)
|
||||||
@@ -1035,12 +1042,94 @@ static void tegra_cursor_atomic_disable(struct drm_plane *plane,
|
|||||||
tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
|
tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int tegra_cursor_atomic_async_check(struct drm_plane *plane,
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
|
||||||
|
struct drm_atomic_state *state)
|
||||||
|
{
|
||||||
|
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
|
||||||
|
#else
|
||||||
|
struct drm_plane_state *new_state)
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
struct drm_crtc_state *crtc_state;
|
||||||
|
int min_scale, max_scale;
|
||||||
|
int err;
|
||||||
|
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
|
||||||
|
crtc_state = drm_atomic_get_existing_crtc_state(state, new_state->crtc);
|
||||||
|
#else
|
||||||
|
crtc_state = drm_atomic_get_existing_crtc_state(new_state->state,
|
||||||
|
new_state->crtc);
|
||||||
|
#endif
|
||||||
|
if (WARN_ON(!crtc_state))
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (!crtc_state->active)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
if (plane->state->crtc != new_state->crtc ||
|
||||||
|
plane->state->src_w != new_state->src_w ||
|
||||||
|
plane->state->src_h != new_state->src_h ||
|
||||||
|
plane->state->crtc_w != new_state->crtc_w ||
|
||||||
|
plane->state->crtc_h != new_state->crtc_h ||
|
||||||
|
plane->state->fb != new_state->fb ||
|
||||||
|
plane->state->fb == NULL)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
min_scale = (1 << 16) / 8;
|
||||||
|
max_scale = (8 << 16) / 1;
|
||||||
|
|
||||||
|
err = drm_atomic_helper_check_plane_state(new_state, crtc_state, min_scale, max_scale,
|
||||||
|
true, true);
|
||||||
|
if (err < 0)
|
||||||
|
return err;
|
||||||
|
|
||||||
|
if (new_state->visible != plane->state->visible)
|
||||||
|
return -EINVAL;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void tegra_cursor_atomic_async_update(struct drm_plane *plane,
|
||||||
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 13, 0)
|
||||||
|
struct drm_atomic_state *state)
|
||||||
|
{
|
||||||
|
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
|
||||||
|
#else
|
||||||
|
struct drm_plane_state *new_state)
|
||||||
|
{
|
||||||
|
#endif
|
||||||
|
struct tegra_dc *dc = to_tegra_dc(new_state->crtc);
|
||||||
|
|
||||||
|
plane->state->src_x = new_state->src_x;
|
||||||
|
plane->state->src_y = new_state->src_y;
|
||||||
|
plane->state->crtc_x = new_state->crtc_x;
|
||||||
|
plane->state->crtc_y = new_state->crtc_y;
|
||||||
|
|
||||||
|
if (new_state->visible) {
|
||||||
|
struct tegra_plane *p = to_tegra_plane(plane);
|
||||||
|
u32 value;
|
||||||
|
|
||||||
|
__tegra_cursor_atomic_update(plane, new_state);
|
||||||
|
|
||||||
|
value = (WIN_A_ACT_REQ << p->index) << 8 | GENERAL_UPDATE;
|
||||||
|
tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
|
||||||
|
(void)tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
|
||||||
|
|
||||||
|
value = (WIN_A_ACT_REQ << p->index) | GENERAL_ACT_REQ;
|
||||||
|
tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
|
||||||
|
(void)tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static const struct drm_plane_helper_funcs tegra_cursor_plane_helper_funcs = {
|
static const struct drm_plane_helper_funcs tegra_cursor_plane_helper_funcs = {
|
||||||
.prepare_fb = tegra_plane_prepare_fb,
|
.prepare_fb = tegra_plane_prepare_fb,
|
||||||
.cleanup_fb = tegra_plane_cleanup_fb,
|
.cleanup_fb = tegra_plane_cleanup_fb,
|
||||||
.atomic_check = tegra_cursor_atomic_check,
|
.atomic_check = tegra_cursor_atomic_check,
|
||||||
.atomic_update = tegra_cursor_atomic_update,
|
.atomic_update = tegra_cursor_atomic_update,
|
||||||
.atomic_disable = tegra_cursor_atomic_disable,
|
.atomic_disable = tegra_cursor_atomic_disable,
|
||||||
|
.atomic_async_check = tegra_cursor_atomic_async_check,
|
||||||
|
.atomic_async_update = tegra_cursor_atomic_async_update,
|
||||||
};
|
};
|
||||||
|
|
||||||
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)
|
#if LINUX_VERSION_CODE >= KERNEL_VERSION(5, 14, 0)
|
||||||
|
|||||||
Reference in New Issue
Block a user