Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 9db4a9c7 authored by Jesse Barnes's avatar Jesse Barnes Committed by Chris Wilson
Browse files

drm/i915: cleanup per-pipe reg usage



We had some conversions over to the _PIPE macros, but didn't get
everything.  So hide the per-pipe regs with an _ (still used in a few
places for legacy) and add a few _PIPE based macros, then make sure
everyone uses them.

[update: remove usage of non-existent no-op macro]
[update 2: keep modesetting suspend/resume code, update to new reg names]
Signed-off-by: default avatarJesse Barnes <jbarnes@virtuousgeek.org>
[ickle: stylistic cleanups for checkpatch and taste]
Signed-off-by: default avatarChris Wilson <chris@chris-wilson.co.uk>
parent 8d7e3de1
Loading
Loading
Loading
Loading
+10 −10
Original line number Diff line number Diff line
@@ -326,21 +326,21 @@ static int i915_gem_pageflip_info(struct seq_file *m, void *data)
	struct intel_crtc *crtc;

	list_for_each_entry(crtc, &dev->mode_config.crtc_list, base.head) {
		const char *pipe = crtc->pipe ? "B" : "A";
		const char *plane = crtc->plane ? "B" : "A";
		const char pipe = pipe_name(crtc->pipe);
		const char plane = plane_name(crtc->plane);
		struct intel_unpin_work *work;

		spin_lock_irqsave(&dev->event_lock, flags);
		work = crtc->unpin_work;
		if (work == NULL) {
			seq_printf(m, "No flip due on pipe %s (plane %s)\n",
			seq_printf(m, "No flip due on pipe %c (plane %c)\n",
				   pipe, plane);
		} else {
			if (!work->pending) {
				seq_printf(m, "Flip queued on pipe %s (plane %s)\n",
				seq_printf(m, "Flip queued on pipe %c (plane %c)\n",
					   pipe, plane);
			} else {
				seq_printf(m, "Flip pending (waiting for vsync) on pipe %s (plane %s)\n",
				seq_printf(m, "Flip pending (waiting for vsync) on pipe %c (plane %c)\n",
					   pipe, plane);
			}
			if (work->enable_stall_check)
@@ -458,7 +458,7 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
	struct drm_info_node *node = (struct drm_info_node *) m->private;
	struct drm_device *dev = node->minor->dev;
	drm_i915_private_t *dev_priv = dev->dev_private;
	int ret, i;
	int ret, i, pipe;

	ret = mutex_lock_interruptible(&dev->struct_mutex);
	if (ret)
@@ -471,10 +471,10 @@ static int i915_interrupt_info(struct seq_file *m, void *data)
			   I915_READ(IIR));
		seq_printf(m, "Interrupt mask:      %08x\n",
			   I915_READ(IMR));
		seq_printf(m, "Pipe A stat:         %08x\n",
			   I915_READ(PIPEASTAT));
		seq_printf(m, "Pipe B stat:         %08x\n",
			   I915_READ(PIPEBSTAT));
		for_each_pipe(pipe)
			seq_printf(m, "Pipe %c stat:         %08x\n",
				   pipe_name(pipe),
				   I915_READ(PIPESTAT(pipe)));
	} else {
		seq_printf(m, "North Display Interrupt enable:		%08x\n",
			   I915_READ(DEIER));
+6 −1
Original line number Diff line number Diff line
@@ -2005,7 +2005,12 @@ int i915_driver_load(struct drm_device *dev, unsigned long flags)
	spin_lock_init(&dev_priv->irq_lock);
	spin_lock_init(&dev_priv->error_lock);

	ret = drm_vblank_init(dev, I915_NUM_PIPE);
	if (IS_MOBILE(dev) || !IS_GEN2(dev))
		dev_priv->num_pipe = 2;
	else
		dev_priv->num_pipe = 1;

	ret = drm_vblank_init(dev, dev_priv->num_pipe);
	if (ret)
		goto out_gem_unload;

+8 −4
Original line number Diff line number Diff line
@@ -50,17 +50,22 @@
enum pipe {
	PIPE_A = 0,
	PIPE_B,
	PIPE_C,
	I915_MAX_PIPES
};
#define pipe_name(p) ((p) + 'A')

enum plane {
	PLANE_A = 0,
	PLANE_B,
	PLANE_C,
};

#define I915_NUM_PIPE	2
#define plane_name(p) ((p) + 'A')

#define I915_GEM_GPU_DOMAINS	(~(I915_GEM_DOMAIN_CPU | I915_GEM_DOMAIN_GTT))

#define for_each_pipe(p) for ((p) = 0; (p) < dev_priv->num_pipe; (p)++)

/* Interface history:
 *
 * 1.1: Original.
@@ -143,8 +148,7 @@ struct intel_display_error_state;
struct drm_i915_error_state {
	u32 eir;
	u32 pgtbl_er;
	u32 pipeastat;
	u32 pipebstat;
	u32 pipestat[I915_MAX_PIPES];
	u32 ipeir;
	u32 ipehr;
	u32 instdone;
+66 −83
Original line number Diff line number Diff line
@@ -85,21 +85,11 @@ ironlake_disable_display_irq(drm_i915_private_t *dev_priv, u32 mask)
	}
}

static inline u32
i915_pipestat(int pipe)
{
	if (pipe == 0)
		return PIPEASTAT;
	if (pipe == 1)
		return PIPEBSTAT;
	BUG();
}

void
i915_enable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
{
	if ((dev_priv->pipestat[pipe] & mask) != mask) {
		u32 reg = i915_pipestat(pipe);
		u32 reg = PIPESTAT(pipe);

		dev_priv->pipestat[pipe] |= mask;
		/* Enable the interrupt, clear any pending status */
@@ -112,7 +102,7 @@ void
i915_disable_pipestat(drm_i915_private_t *dev_priv, int pipe, u32 mask)
{
	if ((dev_priv->pipestat[pipe] & mask) != 0) {
		u32 reg = i915_pipestat(pipe);
		u32 reg = PIPESTAT(pipe);

		dev_priv->pipestat[pipe] &= ~mask;
		I915_WRITE(reg, dev_priv->pipestat[pipe]);
@@ -171,12 +161,12 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)

	if (!i915_pipe_enabled(dev, pipe)) {
		DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
				"pipe %d\n", pipe);
				"pipe %c\n", pipe_name(pipe));
		return 0;
	}

	high_frame = pipe ? PIPEBFRAMEHIGH : PIPEAFRAMEHIGH;
	low_frame = pipe ? PIPEBFRAMEPIXEL : PIPEAFRAMEPIXEL;
	high_frame = PIPEFRAME(pipe);
	low_frame = PIPEFRAMEPIXEL(pipe);

	/*
	 * High & low register fields aren't synchronized, so make sure
@@ -197,11 +187,11 @@ u32 i915_get_vblank_counter(struct drm_device *dev, int pipe)
u32 gm45_get_vblank_counter(struct drm_device *dev, int pipe)
{
	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
	int reg = pipe ? PIPEB_FRMCOUNT_GM45 : PIPEA_FRMCOUNT_GM45;
	int reg = PIPE_FRMCOUNT_GM45(pipe);

	if (!i915_pipe_enabled(dev, pipe)) {
		DRM_DEBUG_DRIVER("trying to get vblank count for disabled "
					"pipe %d\n", pipe);
				 "pipe %c\n", pipe_name(pipe));
		return 0;
	}

@@ -219,7 +209,7 @@ int i915_get_crtc_scanoutpos(struct drm_device *dev, int pipe,

	if (!i915_pipe_enabled(dev, pipe)) {
		DRM_DEBUG_DRIVER("trying to get scanoutpos for disabled "
					"pipe %d\n", pipe);
				 "pipe %c\n", pipe_name(pipe));
		return 0;
	}

@@ -417,6 +407,7 @@ static void pch_irq_handler(struct drm_device *dev)
{
	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
	u32 pch_iir;
	int pipe;

	pch_iir = I915_READ(SDEIIR);

@@ -437,13 +428,11 @@ static void pch_irq_handler(struct drm_device *dev)
	if (pch_iir & SDE_POISON)
		DRM_ERROR("PCH poison interrupt\n");

	if (pch_iir & SDE_FDI_MASK) {
		u32 fdia, fdib;

		fdia = I915_READ(FDI_RXA_IIR);
		fdib = I915_READ(FDI_RXB_IIR);
		DRM_DEBUG_DRIVER("PCH FDI RX interrupt; FDI RXA IIR: 0x%08x, FDI RXB IIR: 0x%08x\n", fdia, fdib);
	}
	if (pch_iir & SDE_FDI_MASK)
		for_each_pipe(pipe)
			DRM_DEBUG_DRIVER("  pipe %c FDI IIR: 0x%08x\n",
					 pipe_name(pipe),
					 I915_READ(FDI_RX_IIR(pipe)));

	if (pch_iir & (SDE_TRANSB_CRC_DONE | SDE_TRANSA_CRC_DONE))
		DRM_DEBUG_DRIVER("PCH transcoder CRC done interrupt\n");
@@ -770,7 +759,7 @@ static void i915_capture_error_state(struct drm_device *dev)
	struct drm_i915_gem_object *obj;
	struct drm_i915_error_state *error;
	unsigned long flags;
	int i;
	int i, pipe;

	spin_lock_irqsave(&dev_priv->error_lock, flags);
	error = dev_priv->first_error;
@@ -778,6 +767,7 @@ static void i915_capture_error_state(struct drm_device *dev)
	if (error)
		return;

	/* Account for pipe specific data like PIPE*STAT */
	error = kmalloc(sizeof(*error), GFP_ATOMIC);
	if (!error) {
		DRM_DEBUG_DRIVER("out of memory, not capturing error state\n");
@@ -790,8 +780,8 @@ static void i915_capture_error_state(struct drm_device *dev)
	error->seqno = dev_priv->ring[RCS].get_seqno(&dev_priv->ring[RCS]);
	error->eir = I915_READ(EIR);
	error->pgtbl_er = I915_READ(PGTBL_ER);
	error->pipeastat = I915_READ(PIPEASTAT);
	error->pipebstat = I915_READ(PIPEBSTAT);
	for_each_pipe(pipe)
		error->pipestat[pipe] = I915_READ(PIPESTAT(pipe));
	error->instpm = I915_READ(INSTPM);
	error->error = 0;
	if (INTEL_INFO(dev)->gen >= 6) {
@@ -912,6 +902,7 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
{
	struct drm_i915_private *dev_priv = dev->dev_private;
	u32 eir = I915_READ(EIR);
	int pipe;

	if (!eir)
		return;
@@ -960,14 +951,10 @@ static void i915_report_and_clear_eir(struct drm_device *dev)
	}

	if (eir & I915_ERROR_MEMORY_REFRESH) {
		u32 pipea_stats = I915_READ(PIPEASTAT);
		u32 pipeb_stats = I915_READ(PIPEBSTAT);

		printk(KERN_ERR "memory refresh error\n");
		printk(KERN_ERR "PIPEASTAT: 0x%08x\n",
		       pipea_stats);
		printk(KERN_ERR "PIPEBSTAT: 0x%08x\n",
		       pipeb_stats);
		printk(KERN_ERR "memory refresh error:\n");
		for_each_pipe(pipe)
			printk(KERN_ERR "pipe %c stat: 0x%08x\n",
			       pipe_name(pipe), I915_READ(PIPESTAT(pipe)));
		/* pipestat has already been acked */
	}
	if (eir & I915_ERROR_INSTRUCTION) {
@@ -1081,10 +1068,10 @@ static void i915_pageflip_stall_check(struct drm_device *dev, int pipe)
	/* Potential stall - if we see that the flip has happened, assume a missed interrupt */
	obj = work->pending_flip_obj;
	if (INTEL_INFO(dev)->gen >= 4) {
		int dspsurf = intel_crtc->plane == 0 ? DSPASURF : DSPBSURF;
		int dspsurf = DSPSURF(intel_crtc->plane);
		stall_detected = I915_READ(dspsurf) == obj->gtt_offset;
	} else {
		int dspaddr = intel_crtc->plane == 0 ? DSPAADDR : DSPBADDR;
		int dspaddr = DSPADDR(intel_crtc->plane);
		stall_detected = I915_READ(dspaddr) == (obj->gtt_offset +
							crtc->y * crtc->fb->pitch +
							crtc->x * crtc->fb->bits_per_pixel/8);
@@ -1104,12 +1091,13 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
	struct drm_i915_master_private *master_priv;
	u32 iir, new_iir;
	u32 pipea_stats, pipeb_stats;
	u32 pipe_stats[I915_MAX_PIPES];
	u32 vblank_status;
	int vblank = 0;
	unsigned long irqflags;
	int irq_received;
	int ret = IRQ_NONE;
	int ret = IRQ_NONE, pipe;
	bool blc_event = false;

	atomic_inc(&dev_priv->irq_received);

@@ -1132,27 +1120,23 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
		 * interrupts (for non-MSI).
		 */
		spin_lock_irqsave(&dev_priv->irq_lock, irqflags);
		pipea_stats = I915_READ(PIPEASTAT);
		pipeb_stats = I915_READ(PIPEBSTAT);

		if (iir & I915_RENDER_COMMAND_PARSER_ERROR_INTERRUPT)
			i915_handle_error(dev, false);

		for_each_pipe(pipe) {
			int reg = PIPESTAT(pipe);
			pipe_stats[pipe] = I915_READ(reg);

			/*
		 * Clear the PIPE(A|B)STAT regs before the IIR
			 * Clear the PIPE*STAT regs before the IIR
			 */
		if (pipea_stats & 0x8000ffff) {
			if (pipea_stats &  PIPE_FIFO_UNDERRUN_STATUS)
				DRM_DEBUG_DRIVER("pipe a underrun\n");
			I915_WRITE(PIPEASTAT, pipea_stats);
			if (pipe_stats[pipe] & 0x8000ffff) {
				if (pipe_stats[pipe] & PIPE_FIFO_UNDERRUN_STATUS)
					DRM_DEBUG_DRIVER("pipe %c underrun\n",
							 pipe_name(pipe));
				I915_WRITE(reg, pipe_stats[pipe]);
				irq_received = 1;
			}

		if (pipeb_stats & 0x8000ffff) {
			if (pipeb_stats &  PIPE_FIFO_UNDERRUN_STATUS)
				DRM_DEBUG_DRIVER("pipe b underrun\n");
			I915_WRITE(PIPEBSTAT, pipeb_stats);
			irq_received = 1;
		}
		spin_unlock_irqrestore(&dev_priv->irq_lock, irqflags);

@@ -1203,27 +1187,22 @@ irqreturn_t i915_driver_irq_handler(DRM_IRQ_ARGS)
				intel_finish_page_flip_plane(dev, 1);
		}

		if (pipea_stats & vblank_status &&
		    drm_handle_vblank(dev, 0)) {
		for_each_pipe(pipe) {
			if (pipe_stats[pipe] & vblank_status &&
			    drm_handle_vblank(dev, pipe)) {
				vblank++;
				if (!dev_priv->flip_pending_is_done) {
				i915_pageflip_stall_check(dev, 0);
				intel_finish_page_flip(dev, 0);
					i915_pageflip_stall_check(dev, pipe);
					intel_finish_page_flip(dev, pipe);
				}
			}

		if (pipeb_stats & vblank_status &&
		    drm_handle_vblank(dev, 1)) {
			vblank++;
			if (!dev_priv->flip_pending_is_done) {
				i915_pageflip_stall_check(dev, 1);
				intel_finish_page_flip(dev, 1);
			}
			if (pipe_stats[pipe] & PIPE_LEGACY_BLC_EVENT_STATUS)
				blc_event = true;
		}

		if ((pipea_stats & PIPE_LEGACY_BLC_EVENT_STATUS) ||
		    (pipeb_stats & PIPE_LEGACY_BLC_EVENT_STATUS) ||
		    (iir & I915_ASLE_INTERRUPT))

		if (blc_event || (iir & I915_ASLE_INTERRUPT))
			intel_opregion_asle_intr(dev);

		/* With MSI, interrupts are only generated when iir
@@ -1634,6 +1613,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
			   DE_PLANEA_FLIP_DONE | DE_PLANEB_FLIP_DONE;
	u32 render_irqs;
	u32 hotplug_mask;
	int pipe;

	dev_priv->irq_mask = ~display_mask;

@@ -1668,8 +1648,8 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
		hotplug_mask = SDE_CRT_HOTPLUG | SDE_PORTB_HOTPLUG |
			       SDE_PORTC_HOTPLUG | SDE_PORTD_HOTPLUG;
		hotplug_mask |= SDE_AUX_MASK | SDE_FDI_MASK | SDE_TRANS_MASK;
		I915_WRITE(FDI_RXA_IMR, 0);
		I915_WRITE(FDI_RXB_IMR, 0);
		for_each_pipe(pipe)
			I915_WRITE(FDI_RX_IMR(pipe), 0);
	}

	dev_priv->pch_irq_mask = ~hotplug_mask;
@@ -1692,6 +1672,7 @@ static int ironlake_irq_postinstall(struct drm_device *dev)
void i915_driver_irq_preinstall(struct drm_device * dev)
{
	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
	int pipe;

	atomic_set(&dev_priv->irq_received, 0);
	atomic_set(&dev_priv->vblank_enabled, 0);
@@ -1711,8 +1692,8 @@ void i915_driver_irq_preinstall(struct drm_device * dev)
	}

	I915_WRITE(HWSTAM, 0xeffe);
	I915_WRITE(PIPEASTAT, 0);
	I915_WRITE(PIPEBSTAT, 0);
	for_each_pipe(pipe)
		I915_WRITE(PIPESTAT(pipe), 0);
	I915_WRITE(IMR, 0xffffffff);
	I915_WRITE(IER, 0x0);
	POSTING_READ(IER);
@@ -1824,6 +1805,7 @@ static void ironlake_irq_uninstall(struct drm_device *dev)
void i915_driver_irq_uninstall(struct drm_device * dev)
{
	drm_i915_private_t *dev_priv = (drm_i915_private_t *) dev->dev_private;
	int pipe;

	if (!dev_priv)
		return;
@@ -1841,12 +1823,13 @@ void i915_driver_irq_uninstall(struct drm_device * dev)
	}

	I915_WRITE(HWSTAM, 0xffffffff);
	I915_WRITE(PIPEASTAT, 0);
	I915_WRITE(PIPEBSTAT, 0);
	for_each_pipe(pipe)
		I915_WRITE(PIPESTAT(pipe), 0);
	I915_WRITE(IMR, 0xffffffff);
	I915_WRITE(IER, 0x0);

	I915_WRITE(PIPEASTAT, I915_READ(PIPEASTAT) & 0x8000ffff);
	I915_WRITE(PIPEBSTAT, I915_READ(PIPEBSTAT) & 0x8000ffff);
	for_each_pipe(pipe)
		I915_WRITE(PIPESTAT(pipe),
			   I915_READ(PIPESTAT(pipe)) & 0x8000ffff);
	I915_WRITE(IIR, I915_READ(IIR));
}
+231 −201

File changed.

Preview size limit exceeded, changes collapsed.

Loading