[PATCH v1] drm/tegra: Trade overlay plane for cursor on older Tegra's

2017-12-17 Thread Dmitry Osipenko
Older Tegra's do not support RGBA format for the cursor, but instead
overlay plane could be used for it. Since there is no much use for the
overlays on a regular desktop and HW-accelerated cursor is much nicer
than the jerky SW cursor, let's trade one overlay plane for the cursor.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/tegra/dc.c | 52 +-
 1 file changed, 37 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 7e58143f4145..3282aa911351 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -125,9 +125,10 @@ static inline u32 compute_initial_dda(unsigned int in)
return dfixed_frac(inf);
 }
 
-static void tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
+static void tegra_dc_setup_window(struct tegra_dc *dc, struct drm_plane *plane,
  const struct tegra_dc_window *window)
 {
+   struct tegra_plane *p = to_tegra_plane(plane);
unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
unsigned long value, flags;
bool yuv, planar;
@@ -144,7 +145,7 @@ static void tegra_dc_setup_window(struct tegra_dc *dc, 
unsigned int index,
 
spin_lock_irqsave(>lock, flags);
 
-   value = WINDOW_A_SELECT << index;
+   value = WINDOW_A_SELECT << p->index;
tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
 
tegra_dc_writel(dc, window->format, DC_WIN_COLOR_DEPTH);
@@ -275,23 +276,29 @@ static void tegra_dc_setup_window(struct tegra_dc *dc, 
unsigned int index,
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_NOKEY);
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_1WIN);
 
-   switch (index) {
+   switch (p->index) {
case 0:
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_X);
-   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_Y);
+   tegra_dc_writel(dc, 0x08, DC_WIN_BLEND_2WIN_Y);
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_3WIN_XY);
break;
 
case 1:
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_X);
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_Y);
-   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_3WIN_XY);
+   tegra_dc_writel(dc, 0x08, DC_WIN_BLEND_3WIN_XY);
break;
 
case 2:
-   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_X);
-   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_Y);
-   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_3WIN_XY);
+   if (plane->type == DRM_PLANE_TYPE_CURSOR) {
+   tegra_dc_writel(dc, 0x04, DC_WIN_BLEND_2WIN_X);
+   tegra_dc_writel(dc, 0x04, DC_WIN_BLEND_2WIN_Y);
+   tegra_dc_writel(dc, 0x04, DC_WIN_BLEND_3WIN_XY);
+   } else {
+   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_X);
+   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_Y);
+   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_3WIN_XY);
+   }
break;
}
 
@@ -438,7 +445,6 @@ static void tegra_plane_atomic_update(struct drm_plane 
*plane,
struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
struct tegra_dc *dc = to_tegra_dc(plane->state->crtc);
struct drm_framebuffer *fb = plane->state->fb;
-   struct tegra_plane *p = to_tegra_plane(plane);
struct tegra_dc_window window;
unsigned int i;
 
@@ -480,7 +486,7 @@ static void tegra_plane_atomic_update(struct drm_plane 
*plane,
window.stride[i] = fb->pitches[i];
}
 
-   tegra_dc_setup_window(dc, p->index, );
+   tegra_dc_setup_window(dc, plane, );
 }
 
 static const struct drm_plane_helper_funcs tegra_plane_helper_funcs = {
@@ -775,9 +781,11 @@ static const u32 tegra124_overlay_formats[] = {
 
 static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
   struct tegra_dc *dc,
-  unsigned int index)
+  unsigned int index,
+  bool cursor)
 {
struct tegra_plane *plane;
+   enum drm_plane_type type;
unsigned int num_formats;
const u32 *formats;
int err;
@@ -793,11 +801,14 @@ static struct drm_plane 
*tegra_dc_overlay_plane_create(struct drm_device *drm,
 
num_formats = dc->soc->num_overlay_formats;
formats = dc->soc->overlay_formats;
+   type = DRM_PLANE_TYPE_OVERLAY;
+
+   if (cursor)
+   type = DRM_PLANE_TYPE_CURSOR;
 
err = drm_universal_plane_init(drm, >base, 1 << dc->pipe,
   

[PATCH v1] drm/tegra: Trade overlay plane for cursor on older Tegra's

2017-12-17 Thread Dmitry Osipenko
Older Tegra's do not support RGBA format for the cursor, but instead
overlay plane could be used for it. Since there is no much use for the
overlays on a regular desktop and HW-accelerated cursor is much nicer
than the jerky SW cursor, let's trade one overlay plane for the cursor.

Signed-off-by: Dmitry Osipenko 
---
 drivers/gpu/drm/tegra/dc.c | 52 +-
 1 file changed, 37 insertions(+), 15 deletions(-)

diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 7e58143f4145..3282aa911351 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -125,9 +125,10 @@ static inline u32 compute_initial_dda(unsigned int in)
return dfixed_frac(inf);
 }
 
-static void tegra_dc_setup_window(struct tegra_dc *dc, unsigned int index,
+static void tegra_dc_setup_window(struct tegra_dc *dc, struct drm_plane *plane,
  const struct tegra_dc_window *window)
 {
+   struct tegra_plane *p = to_tegra_plane(plane);
unsigned h_offset, v_offset, h_size, v_size, h_dda, v_dda, bpp;
unsigned long value, flags;
bool yuv, planar;
@@ -144,7 +145,7 @@ static void tegra_dc_setup_window(struct tegra_dc *dc, 
unsigned int index,
 
spin_lock_irqsave(>lock, flags);
 
-   value = WINDOW_A_SELECT << index;
+   value = WINDOW_A_SELECT << p->index;
tegra_dc_writel(dc, value, DC_CMD_DISPLAY_WINDOW_HEADER);
 
tegra_dc_writel(dc, window->format, DC_WIN_COLOR_DEPTH);
@@ -275,23 +276,29 @@ static void tegra_dc_setup_window(struct tegra_dc *dc, 
unsigned int index,
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_NOKEY);
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_1WIN);
 
-   switch (index) {
+   switch (p->index) {
case 0:
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_X);
-   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_Y);
+   tegra_dc_writel(dc, 0x08, DC_WIN_BLEND_2WIN_Y);
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_3WIN_XY);
break;
 
case 1:
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_X);
tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_Y);
-   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_3WIN_XY);
+   tegra_dc_writel(dc, 0x08, DC_WIN_BLEND_3WIN_XY);
break;
 
case 2:
-   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_X);
-   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_Y);
-   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_3WIN_XY);
+   if (plane->type == DRM_PLANE_TYPE_CURSOR) {
+   tegra_dc_writel(dc, 0x04, DC_WIN_BLEND_2WIN_X);
+   tegra_dc_writel(dc, 0x04, DC_WIN_BLEND_2WIN_Y);
+   tegra_dc_writel(dc, 0x04, DC_WIN_BLEND_3WIN_XY);
+   } else {
+   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_X);
+   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_2WIN_Y);
+   tegra_dc_writel(dc, 0x00, DC_WIN_BLEND_3WIN_XY);
+   }
break;
}
 
@@ -438,7 +445,6 @@ static void tegra_plane_atomic_update(struct drm_plane 
*plane,
struct tegra_plane_state *state = to_tegra_plane_state(plane->state);
struct tegra_dc *dc = to_tegra_dc(plane->state->crtc);
struct drm_framebuffer *fb = plane->state->fb;
-   struct tegra_plane *p = to_tegra_plane(plane);
struct tegra_dc_window window;
unsigned int i;
 
@@ -480,7 +486,7 @@ static void tegra_plane_atomic_update(struct drm_plane 
*plane,
window.stride[i] = fb->pitches[i];
}
 
-   tegra_dc_setup_window(dc, p->index, );
+   tegra_dc_setup_window(dc, plane, );
 }
 
 static const struct drm_plane_helper_funcs tegra_plane_helper_funcs = {
@@ -775,9 +781,11 @@ static const u32 tegra124_overlay_formats[] = {
 
 static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
   struct tegra_dc *dc,
-  unsigned int index)
+  unsigned int index,
+  bool cursor)
 {
struct tegra_plane *plane;
+   enum drm_plane_type type;
unsigned int num_formats;
const u32 *formats;
int err;
@@ -793,11 +801,14 @@ static struct drm_plane 
*tegra_dc_overlay_plane_create(struct drm_device *drm,
 
num_formats = dc->soc->num_overlay_formats;
formats = dc->soc->overlay_formats;
+   type = DRM_PLANE_TYPE_OVERLAY;
+
+   if (cursor)
+   type = DRM_PLANE_TYPE_CURSOR;
 
err = drm_universal_plane_init(drm, >base, 1 << dc->pipe,
   _plane_funcs, formats,
-