From: Dmitry Osipenko <digetx@gmail.com>
To: "Laurent Pinchart" <laurent.pinchart+renesas@ideasonboard.com>,
"Ville Syrjälä" <ville.syrjala@linux.intel.com>,
"Thierry Reding" <thierry.reding@gmail.com>,
"Neil Armstrong" <narmstrong@baylibre.com>,
"Maxime Ripard" <maxime.ripard@free-electrons.com>,
dri-devel@lists.freedesktop.org,
"Paul Kocialkowski" <paul.kocialkowski@bootlin.com>
Cc: linux-media@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
Russell King <linux@armlinux.org.uk>,
Ben Skeggs <bskeggs@redhat.com>, Sinclair Yeh <syeh@vmware.com>,
Thomas Hellstrom <thellstrom@vmware.com>,
Jani Nikula <jani.nikula@linux.intel.com>,
Joonas Lahtinen <joonas.lahtinen@linux.intel.com>,
Rodrigo Vivi <rodrigo.vivi@intel.com>,
linux-tegra@vger.kernel.org, linux-kernel@vger.kernel.org
Subject: [RFC PATCH v3 2/2] drm/tegra: plane: Implement generic colorkey property for older Tegra's
Date: Mon, 4 Jun 2018 01:00:59 +0300 [thread overview]
Message-ID: <20180603220059.17670-3-digetx@gmail.com> (raw)
In-Reply-To: <20180603220059.17670-1-digetx@gmail.com>
For the starter a minimal color keying support is implemented, which is
enough to provide userspace like Opentegra Xorg driver with ability to
support color keying by the XVideo extension.
Signed-off-by: Dmitry Osipenko <digetx@gmail.com>
---
drivers/gpu/drm/tegra/dc.c | 25 +++++++++
drivers/gpu/drm/tegra/dc.h | 7 +++
drivers/gpu/drm/tegra/plane.c | 102 ++++++++++++++++++++++++++++++++++
3 files changed, 134 insertions(+)
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index c3afe7b2237e..685a0fedb01d 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -162,6 +162,7 @@ static void tegra_plane_setup_blending_legacy(struct tegra_plane *plane)
u32 foreground = BLEND_WEIGHT1(255) | BLEND_WEIGHT0(255) |
BLEND_COLOR_KEY_NONE;
u32 blendnokey = BLEND_WEIGHT1(255) | BLEND_WEIGHT0(255);
+ enum drm_plane_colorkey_mode mode;
struct tegra_plane_state *state;
u32 blending[2];
unsigned int i;
@@ -171,7 +172,15 @@ static void tegra_plane_setup_blending_legacy(struct tegra_plane *plane)
tegra_plane_writel(plane, foreground, DC_WIN_BLEND_1WIN);
state = to_tegra_plane_state(plane->base.state);
+ mode = plane->base.state->colorkey.mode;
+ /* setup color keying */
+ if (mode == DRM_PLANE_COLORKEY_MODE_FOREGROUND_CLIP) {
+ /* color key matched areas are transparent */
+ foreground = background[0] | BLEND_COLOR_KEY_0;
+ }
+
+ /* setup alpha blending */
if (state->opaque) {
/*
* Since custom fix-weight blending isn't utilized and weight
@@ -792,6 +801,11 @@ static struct drm_plane *tegra_primary_plane_create(struct drm_device *drm,
dev_err(dc->dev, "failed to create rotation property: %d\n",
err);
+ if (dc->soc->has_legacy_blending)
+ drm_plane_create_colorkey_properties(&plane->base,
+ BIT(DRM_PLANE_COLORKEY_MODE_DISABLED) |
+ BIT(DRM_PLANE_COLORKEY_MODE_FOREGROUND_CLIP));
+
return &plane->base;
}
@@ -1077,6 +1091,11 @@ static struct drm_plane *tegra_dc_overlay_plane_create(struct drm_device *drm,
dev_err(dc->dev, "failed to create rotation property: %d\n",
err);
+ if (dc->soc->has_legacy_blending)
+ drm_plane_create_colorkey_properties(&plane->base,
+ BIT(DRM_PLANE_COLORKEY_MODE_DISABLED) |
+ BIT(DRM_PLANE_COLORKEY_MODE_FOREGROUND_CLIP));
+
return &plane->base;
}
@@ -1187,6 +1206,7 @@ tegra_crtc_atomic_duplicate_state(struct drm_crtc *crtc)
copy->pclk = state->pclk;
copy->div = state->div;
copy->planes = state->planes;
+ copy->ckey = state->ckey;
return ©->base;
}
@@ -1917,6 +1937,11 @@ static void tegra_crtc_atomic_flush(struct drm_crtc *crtc,
struct tegra_dc *dc = to_tegra_dc(crtc);
u32 value;
+ if (dc->soc->has_legacy_blending) {
+ tegra_dc_writel(dc, state->ckey.min, DC_DISP_COLOR_KEY0_LOWER);
+ tegra_dc_writel(dc, state->ckey.max, DC_DISP_COLOR_KEY0_UPPER);
+ }
+
value = state->planes << 8 | GENERAL_UPDATE;
tegra_dc_writel(dc, value, DC_CMD_STATE_CONTROL);
value = tegra_dc_readl(dc, DC_CMD_STATE_CONTROL);
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index e96f582ca692..14ed31f0ff37 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -18,6 +18,11 @@
struct tegra_output;
+struct tegra_dc_color_key_state {
+ u32 min;
+ u32 max;
+};
+
struct tegra_dc_state {
struct drm_crtc_state base;
@@ -26,6 +31,8 @@ struct tegra_dc_state {
unsigned int div;
u32 planes;
+
+ struct tegra_dc_color_key_state ckey;
};
static inline struct tegra_dc_state *to_dc_state(struct drm_crtc_state *state)
diff --git a/drivers/gpu/drm/tegra/plane.c b/drivers/gpu/drm/tegra/plane.c
index d068e8aa3553..b8f05fd6ffcc 100644
--- a/drivers/gpu/drm/tegra/plane.c
+++ b/drivers/gpu/drm/tegra/plane.c
@@ -465,6 +465,104 @@ static int tegra_plane_setup_transparency(struct tegra_plane *tegra,
return 0;
}
+static u32 tegra_plane_convert_colorkey_format(u64 value)
+{
+ /* convert ARGB16161616 to ARGB8888 */
+ u16 a = (value >> 48) & 0xFFFF;
+ u16 r = (value >> 32) & 0xFFFF;
+ u16 g = (value >> 16) & 0xFFFF;
+ u16 b = (value >> 0) & 0xFFFF;
+
+ a = min_t(u16, 0xff, a / 256);
+ r = min_t(u16, 0xff, r / 256);
+ g = min_t(u16, 0xff, g / 256);
+ b = min_t(u16, 0xff, b / 256);
+
+ return (a << 24) | (r << 16) | (g << 8) | b;
+}
+
+static bool tegra_plane_format_invalid_for_colorkey(
+ struct drm_plane_state *state)
+{
+ /*
+ * Older Tegra's do not support alpha channel matching. It should
+ * be possible to support certain cases where planes format has alpha
+ * channel, but for simplicity these cases currently are unsupported.
+ */
+ if (state->fb && __drm_format_has_alpha(state->fb->format->format))
+ return true;
+
+ return false;
+}
+
+static int tegra_plane_setup_colorkey(struct tegra_plane *tegra,
+ struct tegra_plane_state *tegra_state)
+{
+ enum drm_plane_colorkey_mode mode;
+ struct drm_plane_state *old_plane;
+ struct drm_crtc_state *crtc_state;
+ struct tegra_dc_state *dc_state;
+ struct drm_plane_state *state;
+ u64 min, max;
+
+ mode = tegra_state->base.colorkey.mode;
+ min = tegra_state->base.colorkey.min;
+ max = tegra_state->base.colorkey.max;
+
+ /* no need to proceed if color keying is disabled */
+ if (mode == DRM_PLANE_COLORKEY_MODE_DISABLED)
+ return 0;
+
+ state = &tegra_state->base;
+ old_plane = drm_atomic_get_old_plane_state(state->state, &tegra->base);
+
+ /*
+ * Currently color keying implemented for the middle plane only
+ * to simplify things.
+ */
+ if (state->normalized_zpos != 1) {
+ /* foreground-clip has no effect when applied to bottom plane */
+ if (state->normalized_zpos == 0)
+ return 0;
+
+ return -EINVAL;
+ }
+
+ /*
+ * There is no need to proceed, adding CRTC and other planes to
+ * the atomic update, if color keying state is unchanged.
+ */
+ if (old_plane &&
+ old_plane->colorkey.mode == mode &&
+ old_plane->colorkey.min == min &&
+ old_plane->colorkey.max == max)
+ return 0;
+
+ /* convert color key values to HW format */
+ min = tegra_plane_convert_colorkey_format(min);
+ max = tegra_plane_convert_colorkey_format(max);
+
+ /* validate planes format */
+ if (tegra_plane_format_invalid_for_colorkey(state))
+ return -EINVAL;
+
+ /*
+ * Tegra's HW stores color key values within CRTC, hence adjust
+ * planes CRTC atomic state.
+ */
+ crtc_state = drm_atomic_get_crtc_state(state->state, state->crtc);
+ if (IS_ERR(crtc_state))
+ return PTR_ERR(crtc_state);
+
+ dc_state = to_dc_state(crtc_state);
+
+ /* update CRTC's color key state */
+ dc_state->ckey.min = min;
+ dc_state->ckey.max = max;
+
+ return 0;
+}
+
int tegra_plane_setup_legacy_state(struct tegra_plane *tegra,
struct tegra_plane_state *state)
{
@@ -478,5 +576,9 @@ int tegra_plane_setup_legacy_state(struct tegra_plane *tegra,
if (err < 0)
return err;
+ err = tegra_plane_setup_colorkey(tegra, state);
+ if (err < 0)
+ return err;
+
return 0;
}
--
2.17.0
prev parent reply other threads:[~2018-06-03 22:00 UTC|newest]
Thread overview: 14+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-06-03 22:00 [RFC PATCH v3 0/2] drm: Add generic colorkey plane properties Dmitry Osipenko
2018-06-03 22:00 ` [RFC PATCH v3 1/2] drm: Add generic colorkey properties for DRM planes Dmitry Osipenko
2018-07-06 12:11 ` Maarten Lankhorst
2018-07-06 12:23 ` Ville Syrjälä
2018-07-06 13:05 ` Dmitry Osipenko
2018-07-06 14:10 ` Ville Syrjälä
2018-07-06 14:58 ` Maarten Lankhorst
2018-07-06 14:58 ` Dmitry Osipenko
2018-07-06 15:40 ` Russell King - ARM Linux
2018-07-06 16:32 ` Ville Syrjälä
2018-07-06 16:33 ` Dmitry Osipenko
2018-07-06 17:01 ` Russell King - ARM Linux
2018-07-06 19:48 ` Dmitry Osipenko
2018-06-03 22:00 ` Dmitry Osipenko [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20180603220059.17670-3-digetx@gmail.com \
--to=digetx@gmail.com \
--cc=bskeggs@redhat.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=jani.nikula@linux.intel.com \
--cc=joonas.lahtinen@linux.intel.com \
--cc=laurent.pinchart+renesas@ideasonboard.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=linux-tegra@vger.kernel.org \
--cc=linux@armlinux.org.uk \
--cc=maxime.ripard@free-electrons.com \
--cc=narmstrong@baylibre.com \
--cc=paul.kocialkowski@bootlin.com \
--cc=rodrigo.vivi@intel.com \
--cc=syeh@vmware.com \
--cc=thellstrom@vmware.com \
--cc=thierry.reding@gmail.com \
--cc=ville.syrjala@linux.intel.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).