Commit 042206c0 authored by Francisco Jerez's avatar Francisco Jerez Committed by Ben Skeggs
Browse files

drm/nouveau: Implement the vblank DRM hooks.

parent 63f7fcfe
Loading
Loading
Loading
Loading
+27 −0
Original line number Diff line number Diff line
@@ -29,6 +29,7 @@
#include "nouveau_drv.h"
#include "nouveau_fb.h"
#include "nouveau_fbcon.h"
#include "nouveau_hw.h"

static void
nouveau_user_framebuffer_destroy(struct drm_framebuffer *drm_fb)
@@ -104,3 +105,29 @@ const struct drm_mode_config_funcs nouveau_mode_config_funcs = {
	.output_poll_changed = nouveau_fbcon_output_poll_changed,
};

int
nouveau_vblank_enable(struct drm_device *dev, int crtc)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	if (dev_priv->card_type >= NV_50)
		nv_mask(dev, NV50_PDISPLAY_INTR_EN_1, 0,
			NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc));
	else
		NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0,
			    NV_PCRTC_INTR_0_VBLANK);

	return 0;
}

void
nouveau_vblank_disable(struct drm_device *dev, int crtc)
{
	struct drm_nouveau_private *dev_priv = dev->dev_private;

	if (dev_priv->card_type >= NV_50)
		nv_mask(dev, NV50_PDISPLAY_INTR_EN_1,
			NV50_PDISPLAY_INTR_EN_1_VBLANK_CRTC_(crtc), 0);
	else
		NVWriteCRTC(dev, crtc, NV_PCRTC_INTR_EN_0, 0);
}
+4 −0
Original line number Diff line number Diff line
@@ -397,6 +397,9 @@ static struct drm_driver driver = {
	.irq_postinstall = nouveau_irq_postinstall,
	.irq_uninstall = nouveau_irq_uninstall,
	.irq_handler = nouveau_irq_handler,
	.get_vblank_counter = drm_vblank_count,
	.enable_vblank = nouveau_vblank_enable,
	.disable_vblank = nouveau_vblank_disable,
	.reclaim_buffers = drm_core_reclaim_buffers,
	.ioctls = nouveau_ioctls,
	.fops = {
@@ -407,6 +410,7 @@ static struct drm_driver driver = {
		.mmap = nouveau_ttm_mmap,
		.poll = drm_poll,
		.fasync = drm_fasync,
		.read = drm_read,
#if defined(CONFIG_COMPAT)
		.compat_ioctl = nouveau_compat_ioctl,
#endif
+4 −0
Original line number Diff line number Diff line
@@ -1312,6 +1312,10 @@ extern int nouveau_gem_ioctl_cpu_fini(struct drm_device *, void *,
extern int nouveau_gem_ioctl_info(struct drm_device *, void *,
				  struct drm_file *);

/* nouveau_display.c */
int nouveau_vblank_enable(struct drm_device *dev, int crtc);
void nouveau_vblank_disable(struct drm_device *dev, int crtc);

/* nv10_gpio.c */
int nv10_gpio_get(struct drm_device *dev, enum dcb_gpio_tag tag);
int nv10_gpio_set(struct drm_device *dev, enum dcb_gpio_tag tag, int state);
+3 −2
Original line number Diff line number Diff line
@@ -1017,8 +1017,9 @@ nv_load_state_ext(struct drm_device *dev, int head,

	NVWriteCRTC(dev, head, NV_PCRTC_START, regp->fb_start);

	/* Setting 1 on this value gives you interrupts for every vblank period. */
	NVWriteCRTC(dev, head, NV_PCRTC_INTR_EN_0, 0);
	/* Enable vblank interrupts. */
	NVWriteCRTC(dev, head, NV_PCRTC_INTR_EN_0,
		    (dev->vblank_enabled[head] ? 1 : 0));
	NVWriteCRTC(dev, head, NV_PCRTC_INTR_0, NV_PCRTC_INTR_0_VBLANK);
}

+6 −2
Original line number Diff line number Diff line
@@ -1200,11 +1200,15 @@ nv50_pgraph_irq_handler(struct drm_device *dev)
static void
nouveau_crtc_irq_handler(struct drm_device *dev, int crtc)
{
	if (crtc & 1)
	if (crtc & 1) {
		nv_wr32(dev, NV_CRTC0_INTSTAT, NV_CRTC_INTR_VBLANK);
		drm_handle_vblank(dev, 0);
	}

	if (crtc & 2)
	if (crtc & 2) {
		nv_wr32(dev, NV_CRTC1_INTSTAT, NV_CRTC_INTR_VBLANK);
		drm_handle_vblank(dev, 1);
	}
}

irqreturn_t
Loading