summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorThierry Reding <treding@nvidia.com>2013-12-20 13:58:33 +0100
committerThierry Reding <treding@nvidia.com>2014-01-10 10:15:23 +0100
commit690f3ef351121e8e2c4c9efa1ce6e0da4ff25343 (patch)
tree6db35aa30794d41bbaddfa750af02c656f2b91ee
parentab001efbb59ba6902b7f9743e0fe588ba4f25c38 (diff)
WIP: drm/tegra: Add hardware cursor support
Signed-off-by: Thierry Reding <treding@nvidia.com>
-rw-r--r--drivers/gpu/drm/tegra/dc.c75
-rw-r--r--drivers/gpu/drm/tegra/dc.h9
2 files changed, 81 insertions, 3 deletions
diff --git a/drivers/gpu/drm/tegra/dc.c b/drivers/gpu/drm/tegra/dc.c
index 386f3b4b0094..d6bbac016f6e 100644
--- a/drivers/gpu/drm/tegra/dc.c
+++ b/drivers/gpu/drm/tegra/dc.c
@@ -225,6 +225,79 @@ void tegra_dc_disable_vblank(struct tegra_dc *dc)
spin_unlock_irqrestore(&dc->lock, flags);
}
+static int tegra_dc_cursor_set2(struct drm_crtc *crtc, struct drm_file *file,
+ uint32_t handle, uint32_t width,
+ uint32_t height, int32_t hot_x, int32_t hot_y)
+{
+ struct tegra_dc *dc = to_tegra_dc(crtc);
+ struct drm_gem_object *gem;
+ struct tegra_bo *bo = NULL;
+ unsigned long value;
+ int ret = 0;
+
+ dev_dbg(dc->dev, "> %s(crtc=%p, file=%p, handle=%x, width=%u, height=%u, hot_x=%d, hot_y=%d)\n",
+ __func__, crtc, file, handle, width, height, hot_x, hot_y);
+
+ if (handle) {
+ gem = drm_gem_object_lookup(crtc->dev, file, handle);
+ if (!gem) {
+ ret = -ENOENT;
+ goto out;
+ }
+
+ bo = to_tegra_bo(gem);
+ }
+
+ if (bo) {
+ value = (0 << 28) | (1 << 24) | bo->paddr >> 10;
+ tegra_dc_writel(dc, bo->paddr, DC_DISP_CURSOR_START_ADDR);
+
+ value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
+ value |= CURSOR_ENABLE;
+ tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
+
+ value = tegra_dc_readl(dc, DC_DISP_BLEND_CURSOR_CONTROL);
+ value |= (1 << 24);
+ value &= ~(3 << 16);
+ value &= ~(3 << 8);
+ value &= ~0xff;
+ tegra_dc_writel(dc, value, DC_DISP_BLEND_CURSOR_CONTROL);
+ } else {
+ value = tegra_dc_readl(dc, DC_DISP_DISP_WIN_OPTIONS);
+ value &= ~CURSOR_ENABLE;
+ tegra_dc_writel(dc, value, DC_DISP_DISP_WIN_OPTIONS);
+ }
+
+ tegra_dc_writel(dc, 1 << 15, DC_CMD_STATE_CONTROL);
+ tegra_dc_writel(dc, 1 << 7, DC_CMD_STATE_CONTROL);
+
+ tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
+ tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
+
+out:
+ dev_dbg(dc->dev, "< %s() = %d\n", __func__, ret);
+ return ret;
+}
+
+static int tegra_dc_cursor_move(struct drm_crtc *crtc, int x, int y)
+{
+ struct tegra_dc *dc = to_tegra_dc(crtc);
+ int ret = 0;
+
+ dev_dbg(dc->dev, "> %s(crtc=%p, x=%d, y=%d)\n", __func__, crtc, x, y);
+
+ tegra_dc_writel(dc, (x << 16) | y, DC_DISP_CURSOR_POSITION);
+
+ tegra_dc_writel(dc, 1 << 15, DC_CMD_STATE_CONTROL);
+ tegra_dc_writel(dc, 1 << 7, DC_CMD_STATE_CONTROL);
+
+ tegra_dc_writel(dc, GENERAL_ACT_REQ << 8, DC_CMD_STATE_CONTROL);
+ tegra_dc_writel(dc, GENERAL_ACT_REQ, DC_CMD_STATE_CONTROL);
+
+ dev_dbg(dc->dev, "< %s() = %d\n", __func__, ret);
+ return ret;
+}
+
static void tegra_dc_finish_page_flip(struct tegra_dc *dc)
{
struct drm_device *drm = dc->base.dev;
@@ -301,6 +374,8 @@ static void tegra_dc_destroy(struct drm_crtc *crtc)
}
static const struct drm_crtc_funcs tegra_crtc_funcs = {
+ .cursor_set2 = tegra_dc_cursor_set2,
+ .cursor_move = tegra_dc_cursor_move,
.page_flip = tegra_dc_page_flip,
.set_config = drm_crtc_helper_set_config,
.destroy = tegra_dc_destroy,
diff --git a/drivers/gpu/drm/tegra/dc.h b/drivers/gpu/drm/tegra/dc.h
index c94101494826..e531f1e5addd 100644
--- a/drivers/gpu/drm/tegra/dc.h
+++ b/drivers/gpu/drm/tegra/dc.h
@@ -116,9 +116,10 @@
#define DC_DISP_DISP_SIGNAL_OPTIONS1 0x401
#define DC_DISP_DISP_WIN_OPTIONS 0x402
-#define HDMI_ENABLE (1 << 30)
-#define DSI_ENABLE (1 << 29)
-#define SOR_ENABLE (1 << 25)
+#define HDMI_ENABLE (1 << 30)
+#define DSI_ENABLE (1 << 29)
+#define SOR_ENABLE (1 << 25)
+#define CURSOR_ENABLE (1 << 16)
#define DC_DISP_DISP_MEM_HIGH_PRIORITY 0x403
#define CURSOR_THRESHOLD(x) (((x) & 0x03) << 24)
@@ -302,6 +303,8 @@
#define INTERLACE_START (1 << 1)
#define INTERLACE_ENABLE (1 << 0)
+#define DC_DISP_BLEND_CURSOR_CONTROL 0x4f1
+
#define DC_WIN_CSC_YOF 0x611
#define DC_WIN_CSC_KYRGB 0x612
#define DC_WIN_CSC_KUR 0x613