summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/gma500/blitter.c
diff options
context:
space:
mode:
authorPatrik Jakobsson <patrik.r.jakobsson@gmail.com>2014-01-04 23:58:35 +0400
committerPatrik Jakobsson <patrik.r.jakobsson@gmail.com>2014-03-17 23:11:51 +0400
commit1c6b5d17d6ed124afd55027a72d64b6f6eca501e (patch)
tree627f9676d7693617116bd05a25401773fe2198bd /drivers/gpu/drm/gma500/blitter.c
parentac1b01b0baff00a7576fd98401b728c84aae7210 (diff)
downloadlinux-1c6b5d17d6ed124afd55027a72d64b6f6eca501e.tar.xz
drm/gma500: Add first piece of blitter code
Right now, all we need to know about the blitter is that it's not doing anything that can be messed up when fiddling with MMU mappings. Signed-off-by: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
Diffstat (limited to 'drivers/gpu/drm/gma500/blitter.c')
-rw-r--r--drivers/gpu/drm/gma500/blitter.c51
1 files changed, 51 insertions, 0 deletions
diff --git a/drivers/gpu/drm/gma500/blitter.c b/drivers/gpu/drm/gma500/blitter.c
new file mode 100644
index 000000000000..9cd54a6fb899
--- /dev/null
+++ b/drivers/gpu/drm/gma500/blitter.c
@@ -0,0 +1,51 @@
+/*
+ * Copyright (c) 2014, Patrik Jakobsson
+ * All Rights Reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions of the GNU General Public License,
+ * version 2, as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
+ * more details.
+ *
+ * Authors: Patrik Jakobsson <patrik.r.jakobsson@gmail.com>
+ */
+
+#include "psb_drv.h"
+
+#include "blitter.h"
+#include "psb_reg.h"
+
+/* Wait for the blitter to be completely idle */
+int gma_blt_wait_idle(struct drm_psb_private *dev_priv)
+{
+ unsigned long stop = jiffies + HZ;
+ int busy = 1;
+
+ /* NOP for Cedarview */
+ if (IS_CDV(dev_priv->dev))
+ return 0;
+
+ /* First do a quick check */
+ if ((PSB_RSGX32(PSB_CR_2D_SOCIF) == _PSB_C2_SOCIF_EMPTY) &&
+ ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) & _PSB_C2B_STATUS_BUSY) == 0))
+ return 0;
+
+ do {
+ busy = (PSB_RSGX32(PSB_CR_2D_SOCIF) != _PSB_C2_SOCIF_EMPTY);
+ } while (busy && !time_after_eq(jiffies, stop));
+
+ if (busy)
+ return -EBUSY;
+
+ do {
+ busy = ((PSB_RSGX32(PSB_CR_2D_BLIT_STATUS) &
+ _PSB_C2B_STATUS_BUSY) != 0);
+ } while (busy && !time_after_eq(jiffies, stop));
+
+ /* If still busy, we probably have a hang */
+ return (busy) ? -EBUSY : 0;
+}