[RFC PATCH 1/1] drm/gma500: add atomic support
James Hilliard
james.hilliard1 at gmail.com
Thu Jun 6 20:20:32 UTC 2019
Imported from https://git.tizen.org/cgit/kernel/kernel-mfld-blackbay/
This is currently not functional and based off of an older version of
the gma500 driver. From the commit log this was written by Intel, is
anyone aware of a more up to date version?
I'm looking to see if this would be a decent starting point for adding
gma500 atomic support to mainline and how best to approach that.
Signed-off-by: James Hilliard <james.hilliard1 at gmail.com>
---
drivers/gpu/drm/gma500/Makefile | 1 +
drivers/gpu/drm/gma500/psb_page_flip.c | 600 +++++++++++++++++++++++++
drivers/gpu/drm/gma500/psb_page_flip.h | 38 ++
3 files changed, 639 insertions(+)
create mode 100644 drivers/gpu/drm/gma500/psb_page_flip.c
create mode 100644 drivers/gpu/drm/gma500/psb_page_flip.h
diff --git a/drivers/gpu/drm/gma500/Makefile b/drivers/gpu/drm/gma500/Makefile
index c8f2c89be99d..3db535ef51cb 100644
--- a/drivers/gpu/drm/gma500/Makefile
+++ b/drivers/gpu/drm/gma500/Makefile
@@ -24,6 +24,7 @@ gma500_gfx-y += \
psb_intel_sdvo.o \
psb_lid.o \
psb_irq.o \
+ psb_page_flip.o \
psb_device.o \
mid_bios.o
diff --git a/drivers/gpu/drm/gma500/psb_page_flip.c b/drivers/gpu/drm/gma500/psb_page_flip.c
new file mode 100644
index 000000000000..6a93727cf1c1
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_page_flip.c
@@ -0,0 +1,600 @@
+/*
+ * Copyright (c) 2011-2012, Intel Corporation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,·
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Authors:
+ * Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>
+ * Pauli Nieminen <pauli.nieminen at intel.com>
+ * Ville Syrjälä <ville.syrjala at linux.intel.com>
+ */
+
+#include <linux/spinlock.h>
+#include <linux/list.h>
+
+#include <drm/drmP.h>
+#include "psb_drv.h"
+#include "framebuffer.h"
+#include "psb_intel_reg.h"
+#include "psb_page_flip.h"
+
+#include "mdfld_output.h"
+#include "mdfld_dsi_output.h"
+
+#if defined(CONFIG_MDFLD_DUAL_DSI_DPU)
+#include "mdfld_dsi_dbi_dpu.h"
+#elif defined(CONFIG_MDFLD_DSI_DSR)
+#include "mdfld_dsi_dbi.h"
+#endif
+
+struct pending_flip {
+ struct drm_crtc *crtc;
+ struct drm_pending_vblank_event *event;
+ PVRSRV_KERNEL_MEM_INFO *mem_info;
+ PVRSRV_KERNEL_MEM_INFO *old_mem_info;
+ uint32_t offset;
+ struct list_head uncompleted;
+ struct pvr_pending_sync pending_sync;
+ struct drm_flip base;
+ u32 vbl_count;
+ struct list_head companions;
+ u32 tgid;
+ bool vblank_ref;
+ atomic_t refcnt;
+ struct psb_pending_values pending_values;
+};
+
+enum {
+ /* somwehat arbitrary value */
+ PSB_VBL_CNT_TIMEOUT = 5,
+};
+
+static u32 get_vbl_count(struct drm_crtc *crtc)
+{
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ struct drm_psb_private *dev_priv = crtc->dev->dev_private;
+ int pipe = psb_intel_crtc->pipe;
+ u32 high, low1, low2, dsl;
+ unsigned int timeout = 0;
+
+ /* All reads must be satisfied during the same frame */
+ do {
+ void __iomem *reg_pixel;
+ void __iomem *reg_high;
+
+ reg_pixel = dev_priv->vdc_reg + PSB_PIPEFRAMEPIXEL(pipe);
+ reg_high = dev_priv->vdc_reg + PSB_PIPEFRAMEHIGH(pipe);
+ low1 = ioread32(reg_pixel) >> PIPE_FRAME_LOW_SHIFT;
+ high = ioread32(reg_high) << 8;
+ dsl = ioread32(dev_priv->vdc_reg + PSB_PIPE_DSL(pipe));
+ low2 = ioread32(reg_pixel) >> PIPE_FRAME_LOW_SHIFT;
+ } while (low1 != low2 && timeout++ < PSB_VBL_CNT_TIMEOUT);
+
+ if (timeout >= PSB_VBL_CNT_TIMEOUT)
+ dev_warn(crtc->dev->dev,
+ "Timed out while determining VBL count for pipe %d\n",
+ psb_intel_crtc->pipe);
+
+ /*
+ * The frame counter seems to increment at the beginning of the
+ * last scanline. The hardware performs the flip at the start
+ * of the vblank, so we want to count those events instead.
+ * Cook up a vblank counter from the frame counter and scanline
+ * counter.
+ */
+ return ((high | low2) +
+ ((dsl >= crtc->hwmode.crtc_vdisplay) &&
+ (dsl < crtc->hwmode.crtc_vtotal - 1))) & 0xffffff;
+}
+
+static unsigned int usecs_to_scanlines(struct drm_crtc *crtc,
+ unsigned int usecs)
+{
+ /* paranoia */
+ if (!crtc->hwmode.crtc_htotal)
+ return 1;
+
+ return DIV_ROUND_UP(usecs * crtc->hwmode.clock,
+ 1000 * crtc->hwmode.crtc_htotal);
+}
+
+/* Called with interrupts off. */
+static void avoid_danger_zone(struct drm_crtc *crtc)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ int pipe = psb_intel_crtc->pipe;
+ /*
+ * With CRTC and one overlay we're usually spending 30-40 usecs
+ * between avoid_danger_zone() and psb_flip_driver_flush(). Leave
+ * a small safety margin and avoid flipping while under 60 usec
+ * from the vblank start.
+ */
+ u32 min = crtc->hwmode.crtc_vdisplay - usecs_to_scanlines(crtc, 60);
+ u32 max = crtc->hwmode.crtc_vdisplay - 1;
+ long timeout = msecs_to_jiffies(1);
+ u32 val;
+
+ drm_vblank_get(dev, pipe);
+
+ psb_intel_crtc->vbl_received = false;
+ val = ioread32(dev_priv->vdc_reg + PSB_PIPE_DSL(pipe));
+
+ while (val >= min && val <= max && timeout > 0) {
+ local_irq_enable();
+
+ timeout = wait_event_timeout(psb_intel_crtc->vbl_wait,
+ psb_intel_crtc->vbl_received,
+ timeout);
+
+ local_irq_disable();
+
+ psb_intel_crtc->vbl_received = false;
+ val = ioread32(dev_priv->vdc_reg + PSB_PIPE_DSL(pipe));
+ }
+
+ drm_vblank_put(dev, pipe);
+
+ if (val >= min && val <= max)
+ dev_warn(dev->dev,
+ "Page flipping close to vblank start (DSL=%u, VBL=%u)\n",
+ val, crtc->hwmode.crtc_vdisplay);
+}
+
+void
+psb_cleanup_pending_events(struct drm_device *dev, struct psb_fpriv *priv)
+{
+ struct drm_pending_vblank_event *e;
+ struct pending_flip *pending_flip, *temp;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+ list_for_each_entry_safe(pending_flip, temp, &priv->pending_flips,
+ uncompleted) {
+ e = pending_flip->event;
+ pending_flip->event = NULL;
+ e->base.destroy(&e->base);
+ list_del_init(&pending_flip->uncompleted);
+ }
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static void
+send_page_flip_event(struct drm_device *dev, int pipe,
+ struct pending_flip *pending_flip)
+{
+ struct drm_pending_vblank_event *e;
+ struct timeval now;
+ unsigned long flags;
+
+ spin_lock_irqsave(&dev->event_lock, flags);
+
+ if (!pending_flip->event)
+ goto unlock;
+
+ list_del(&pending_flip->uncompleted);
+ e = pending_flip->event;
+ do_gettimeofday(&now);
+ e->event.sequence = drm_vblank_count(dev, pipe);
+ e->event.tv_sec = now.tv_sec;
+ e->event.tv_usec = now.tv_usec;
+ list_add_tail(&e->base.link,
+ &e->base.file_priv->event_list);
+ wake_up_interruptible(&e->base.file_priv->event_wait);
+
+unlock:
+ spin_unlock_irqrestore(&dev->event_lock, flags);
+}
+
+static void free_flip(struct pending_flip *crtc_flip)
+{
+ if (atomic_dec_and_test(&crtc_flip->refcnt)) {
+ psb_fb_unref(crtc_flip->old_mem_info, crtc_flip->tgid);
+ kfree(crtc_flip);
+ }
+}
+
+static void crtc_flip_cleanup(struct drm_flip *flip)
+{
+ struct pending_flip *crtc_flip =
+ container_of(flip, struct pending_flip, base);
+ struct drm_device *dev = crtc_flip->crtc->dev;
+
+ mutex_lock(&dev->mode_config.mutex);
+ psb_fb_gtt_unref(dev, crtc_flip->mem_info, crtc_flip->tgid);
+ mutex_unlock(&dev->mode_config.mutex);
+
+ free_flip(crtc_flip);
+}
+
+static void crtc_flip_finish(struct drm_flip *flip)
+{
+}
+
+static void psb_flip_driver_flush(struct drm_flip_driver *driver)
+{
+ struct drm_psb_private *dev_priv =
+ container_of(driver, struct drm_psb_private, flip_driver);
+
+ /* Flush posted writes */
+ (void)ioread32(dev_priv->vdc_reg + PSB_PIPESTAT(PSB_PIPE_A));
+}
+
+static void psb_flip_complete_sync_callback(struct pvr_pending_sync *sync,
+ bool call_from_work)
+{
+ struct pending_flip *crtc_flip =
+ container_of(sync, struct pending_flip, pending_sync);
+
+ if (psb_fb_increase_read_ops_completed(crtc_flip->old_mem_info,
+ &crtc_flip->pending_values, sync)) {
+ WARN(true, "Sync callback called without completing operation");
+ return;
+ }
+
+ free_flip(crtc_flip);
+
+ if (call_from_work)
+ mutex_lock(&gPVRSRVLock);
+
+ PVRSRVScheduleDeviceCallbacks();
+
+ if (call_from_work)
+ mutex_unlock(&gPVRSRVLock);
+}
+
+static void crtc_flip_complete(struct drm_flip *flip)
+{
+ struct pending_flip *crtc_flip =
+ container_of(flip, struct pending_flip, base);
+ struct drm_device *dev = crtc_flip->crtc->dev;
+ int pipe = to_psb_intel_crtc(crtc_flip->crtc)->pipe;
+
+ send_page_flip_event(dev, pipe, crtc_flip);
+
+ if (crtc_flip->vblank_ref)
+ drm_vblank_put(dev, pipe);
+
+ atomic_inc(&crtc_flip->refcnt);
+ crtc_flip->pending_sync.callback = psb_flip_complete_sync_callback;
+ if (psb_fb_increase_read_ops_completed(crtc_flip->old_mem_info,
+ &crtc_flip->pending_values,
+ &crtc_flip->pending_sync))
+ return;
+
+ free_flip(crtc_flip);
+ PVRSRVScheduleDeviceCallbacks();
+}
+
+static const struct drm_flip_driver_funcs psb_flip_driver_funcs = {
+ .flush = psb_flip_driver_flush,
+};
+
+void psb_page_flip_init(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ drm_flip_driver_init(&dev_priv->flip_driver,
+ &psb_flip_driver_funcs);
+}
+
+void psb_page_flip_fini(struct drm_device *dev)
+{
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ drm_flip_driver_fini(&dev_priv->flip_driver);
+}
+
+static bool vbl_count_after_eq(u32 a, u32 b)
+{
+ return !((a - b) & 0x800000);
+}
+
+static bool crtc_check(struct drm_flip *pending_flip,
+ u32 vbl_count)
+{
+ struct pending_flip *crtc_flip =
+ container_of(pending_flip, struct pending_flip, base);
+
+ return vbl_count_after_eq(vbl_count, crtc_flip->vbl_count);
+}
+
+static bool crtc_flip(struct drm_flip *flip,
+ struct drm_flip *pending_flip)
+{
+ struct pending_flip *crtc_flip = container_of(flip, struct pending_flip, base);
+ struct drm_crtc *crtc = crtc_flip->crtc;
+ struct drm_device *dev = crtc->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ int pipe = to_psb_intel_crtc(crtc)->pipe;
+ u32 vbl_count;
+
+ crtc_flip->vblank_ref = drm_vblank_get(dev, pipe) == 0;
+
+ vbl_count = get_vbl_count(crtc);
+
+ iowrite32(crtc_flip->offset, dev_priv->vdc_reg + PSB_DSPSURF(pipe));
+
+ /* This flip will happen on the next vblank */
+ crtc_flip->vbl_count = (vbl_count + 1) & 0xffffff;
+
+ if (pending_flip) {
+ struct pending_flip *old_crtc_flip =
+ container_of(pending_flip, struct pending_flip, base);
+ bool flipped = crtc_check(pending_flip, vbl_count);
+
+ if (!flipped) {
+ swap(crtc_flip->old_mem_info, old_crtc_flip->old_mem_info);
+ swap(crtc_flip->pending_values, old_crtc_flip->pending_values);
+ }
+
+ return flipped;
+ }
+
+ return false;
+}
+
+static bool crtc_vblank(struct drm_flip *pending_flip)
+{
+ struct pending_flip *crtc_flip =
+ container_of(pending_flip, struct pending_flip, base);
+ u32 vbl_count = get_vbl_count(crtc_flip->crtc);
+
+ return crtc_check(pending_flip, vbl_count);
+}
+
+static const struct drm_flip_helper_funcs crtc_flip_funcs = {
+ .flip = crtc_flip,
+ .vblank = crtc_vblank,
+ .complete = crtc_flip_complete,
+ .finish = crtc_flip_finish,
+ .cleanup = crtc_flip_cleanup,
+};
+
+void psb_page_flip_crtc_init(struct psb_intel_crtc *psb_intel_crtc)
+{
+ struct drm_device *dev = psb_intel_crtc->base.dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+
+ drm_flip_helper_init(&psb_intel_crtc->flip_helper,
+ &dev_priv->flip_driver,
+ &crtc_flip_funcs);
+}
+
+void psb_page_flip_crtc_fini(struct psb_intel_crtc *psb_intel_crtc)
+{
+ drm_flip_helper_fini(&psb_intel_crtc->flip_helper);
+}
+
+static void
+psb_intel_crtc_process_vblank_real(struct drm_crtc *crtc)
+{
+ struct drm_psb_private *dev_priv = crtc->dev->dev_private;
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ int pipe = psb_intel_crtc->pipe;
+ int i;
+
+ psb_intel_crtc->vbl_received = true;
+ wake_up(&psb_intel_crtc->vbl_wait);
+
+ for (i = 0; i < ARRAY_SIZE(dev_priv->overlays); i++) {
+ if (!dev_priv->overlays[i])
+ continue;
+
+ mdfld_overlay_process_vblank(dev_priv->overlays[i], pipe);
+ }
+
+ drm_flip_helper_vblank(&psb_intel_crtc->flip_helper);
+}
+
+void
+psb_intel_crtc_process_vblank(struct drm_crtc *crtc)
+{
+ struct drm_psb_private *dev_priv = crtc->dev->dev_private;
+ struct psb_intel_crtc *psb_intel_crtc = to_psb_intel_crtc(crtc);
+ int pipe = psb_intel_crtc->pipe;
+ struct drm_connector *connector;
+ struct drm_crtc *hdmicrtc = NULL;
+
+ psb_intel_crtc_process_vblank_real(crtc);
+
+ /* This following is to handle HDMI pending flips if unplug the cable
+ * After HDMI is unpluged, there is no vblank interrupt anymore.
+ * But there may be some pending flips exists in psb_intel_crtc.
+ * We need complet the pending flips.
+ * This can be REVERTED, if the pending flip issue fixed.
+ */
+ if (pipe != 0)
+ return;
+
+ hdmicrtc = dev_priv->pipe_to_crtc_mapping[1];
+ if (!hdmicrtc)
+ return;
+
+ list_for_each_entry(connector,
+ &crtc->dev->mode_config.connector_list, head) {
+ if (connector->connector_type == DRM_MODE_CONNECTOR_DVID &&
+ connector->status == connector_status_disconnected) {
+ psb_intel_crtc_process_vblank_real(hdmicrtc);
+ break;
+ }
+ }
+}
+
+static void
+sync_callback(struct pvr_pending_sync *pending_sync, bool from_misr)
+{
+ struct pending_flip *pending_flip =
+ container_of(pending_sync, struct pending_flip, pending_sync);
+ struct drm_crtc* crtc = pending_flip->crtc;
+ struct drm_device *dev = crtc->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct drm_flip *flip, *next;
+ LIST_HEAD(flips);
+ bool pipe_enabled = false;
+
+ list_add_tail(&pending_flip->base.list, &flips);
+
+ list_for_each_entry_safe(flip, next, &pending_flip->companions, list)
+ list_move_tail(&flip->list, &flips);
+
+ WARN_ON(!list_empty(&pending_flip->companions));
+
+ /* prevent DPMS and whatnot from shooting us in the foot */
+ if (from_misr)
+ mutex_lock(&dev->mode_config.mutex);
+
+ if (ospm_power_using_hw_begin(OSPM_DISPLAY_ISLAND, false)) {
+ int pipe = to_psb_intel_crtc(crtc)->pipe;
+ u32 val;
+
+ val = ioread32(dev_priv->vdc_reg + PSB_PIPECONF(pipe));
+
+ pipe_enabled = val & PIPEACONF_ENABLE;
+
+ if (!pipe_enabled)
+ ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ }
+
+ if (pipe_enabled) {
+ drm_flip_driver_prepare_flips(&dev_priv->flip_driver, &flips);
+
+ /* Make sure we're not interrupted during the critical phase */
+ local_irq_disable();
+
+ /*
+ * If we cross into vblank while programming the flips, we
+ * can't determine which flips have completed. Also when
+ * trying to synchronize multiple flips, we can't be sure
+ * that all flips will happen on the same vblank. So, if
+ * we're close to the start of vblank, wait until we're
+ * safely past it before proceeding any further.
+ */
+ avoid_danger_zone(crtc);
+
+ drm_flip_driver_schedule_flips(&dev_priv->flip_driver, &flips);
+
+ local_irq_enable();
+
+ ospm_power_using_hw_end(OSPM_DISPLAY_ISLAND);
+ } else
+ /* powered off, just complete all pending and new flips */
+ drm_flip_driver_complete_flips(&dev_priv->flip_driver, &flips);
+
+ if (from_misr)
+ mutex_unlock(&dev->mode_config.mutex);
+}
+
+int
+psb_intel_crtc_page_flip(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event)
+{
+ struct drm_device *dev = crtc->dev;
+ struct drm_psb_private *dev_priv = dev->dev_private;
+ struct psb_framebuffer *psbfb = to_psb_fb(fb);
+ PVRSRV_KERNEL_MEM_INFO *current_fb_mem_info;
+ struct pending_flip *new_pending_flip;
+ struct psb_fpriv *priv;
+ struct psb_fbdev *fbdev = NULL;
+ unsigned long flags;
+ u32 tgid = psb_get_tgid();
+ int ret;
+ int pipe = to_psb_intel_crtc(crtc)->pipe;
+ int i;
+
+ if (!psbfb->pvrBO)
+ return -EINVAL;
+
+ new_pending_flip = kzalloc(sizeof *new_pending_flip, GFP_KERNEL);
+ if (!new_pending_flip)
+ return -ENOMEM;
+
+ /* keep a reference to the new fb, until it's no longer scanned out. */
+ ret = psb_fb_gtt_ref(dev, psbfb->pvrBO);
+ if (ret) {
+ kfree(new_pending_flip);
+ return ret;
+ }
+
+ current_fb_mem_info = to_psb_fb(crtc->fb)->pvrBO;
+
+ /* keep a reference to the old fb, for read ops manipulations */
+ ret = psb_fb_ref(current_fb_mem_info);
+ if (ret) {
+ psb_fb_gtt_unref(dev, psbfb->pvrBO, tgid);
+ kfree(new_pending_flip);
+ return ret;
+ }
+
+ drm_flip_init(&new_pending_flip->base, &to_psb_intel_crtc(crtc)->flip_helper);
+
+ atomic_set(&new_pending_flip->refcnt, 1);
+ new_pending_flip->crtc = crtc;
+ new_pending_flip->event = event;
+ new_pending_flip->offset = psbfb->offset;
+
+ if (event) {
+ spin_lock_irqsave(&crtc->dev->event_lock, flags);
+ priv = psb_fpriv(event->base.file_priv);
+ list_add(&new_pending_flip->uncompleted, &priv->pending_flips);
+ spin_unlock_irqrestore(&crtc->dev->event_lock, flags);
+ } else {
+ INIT_LIST_HEAD(&new_pending_flip->uncompleted);
+ }
+
+ /* In page flip, change the psb_fb_helper.fb
+ * and fbdev to the swapped fb.
+ */
+ if (dev->dev_private)
+ fbdev = ((struct drm_psb_private *)dev->dev_private)->fbdev;
+ if (fbdev) {
+ fbdev->psb_fb_helper.fb = fb;
+ fbdev->psb_fb_helper.fbdev = psbfb->fbdev;
+ } else
+ printk(KERN_ALERT "%s cannot find the fb\n", __func__);
+
+ crtc->fb = fb;
+
+ new_pending_flip->mem_info = psbfb->pvrBO;
+ new_pending_flip->old_mem_info = current_fb_mem_info;
+
+ psb_fb_increase_read_ops_pending(current_fb_mem_info,
+ &new_pending_flip->pending_values);
+ psb_fb_flip_trace(current_fb_mem_info, psbfb->pvrBO);
+
+ new_pending_flip->tgid = tgid;
+
+ INIT_LIST_HEAD(&new_pending_flip->companions);
+
+ for (i = 0; i < ARRAY_SIZE(dev_priv->overlays); i++) {
+ struct drm_flip *flip;
+
+ if (!dev_priv->overlays[i])
+ continue;
+
+ flip = mdfld_overlay_atomic_flip(dev_priv->overlays[i], pipe);
+ if (!flip)
+ continue;
+
+ list_add_tail(&flip->list, &new_pending_flip->companions);
+ }
+
+ PVRSRVCallbackOnSync(psbfb->pvrBO->psKernelSyncInfo,
+ PVRSRV_SYNC_WRITE, sync_callback,
+ &new_pending_flip->pending_sync);
+
+ return 0;
+}
diff --git a/drivers/gpu/drm/gma500/psb_page_flip.h b/drivers/gpu/drm/gma500/psb_page_flip.h
new file mode 100644
index 000000000000..60671201d2c8
--- /dev/null
+++ b/drivers/gpu/drm/gma500/psb_page_flip.h
@@ -0,0 +1,38 @@
+/*
+ * Copyright (c) 2011, Intel Corporation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program; if not, write to the Free Software Foundation, Inc.,·
+ * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
+ *
+ * Authors:
+ * Ander Conselvan de Oliveira <ander.conselvan.de.oliveira at intel.com>
+ *
+ */
+
+#ifndef _PSB_PAGE_FLIP_H_
+#define _PSB_PAGE_FLIP_H_
+
+void psb_page_flip_init(struct drm_device *dev);
+void psb_page_flip_fini(struct drm_device *dev);
+
+void psb_page_flip_crtc_init(struct psb_intel_crtc *psb_intel_crtc);
+void psb_page_flip_crtc_fini(struct psb_intel_crtc *psb_intel_crtc);
+
+void psb_intel_crtc_process_vblank(struct drm_crtc *crtc);
+int psb_intel_crtc_page_flip(struct drm_crtc *crtc,
+ struct drm_framebuffer *fb,
+ struct drm_pending_vblank_event *event);
+void psb_cleanup_pending_events(struct drm_device *dev,
+ struct psb_fpriv *priv);
+
+#endif /* _PSB_PAGE_FLIP_H_ */
--
2.20.1
More information about the dri-devel
mailing list