Esempio n. 1
0
int DRM(vblank_wait)(drm_device_t *dev, unsigned int *sequence)
{
  	drm_radeon_private_t *dev_priv = 
	   (drm_radeon_private_t *)dev->dev_private;
	unsigned int cur_vblank;
	int ret = 0;

	if ( !dev_priv ) {
		DRM_ERROR( "%s called with no initialization\n", __FUNCTION__ );
		return DRM_ERR(EINVAL);
	}

	radeon_acknowledge_irqs( dev_priv );

	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;

	/* Assume that the user has missed the current sequence number
	 * by about a day rather than she wants to wait for years
	 * using vertical blanks... 
	 */
	DRM_WAIT_ON( ret, dev->vbl_queue, 3*DRM_HZ, 
		     ( ( ( cur_vblank = atomic_read(&dev->vbl_received ) )
			 - *sequence ) <= (1<<23) ) );

	*sequence = cur_vblank;

	return ret;
}
Esempio n. 2
0
irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
{
	struct drm_device *dev = (struct drm_device *) arg;
	drm_radeon_private_t *dev_priv =
	    (drm_radeon_private_t *) dev->dev_private;
	u32 stat;
	u32 r500_disp_int;

	/* Only consider the bits we're interested in - others could be used
	 * outside the DRM
	 */
	stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int);
	if (!stat)
		return IRQ_NONE;

	stat &= dev_priv->irq_enable_reg;

	/* SW interrupt */
	if (stat & RADEON_SW_INT_TEST)
		DRM_WAKEUP(&dev_priv->swi_queue);

	/* VBLANK interrupt */
	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690) {
		if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
			drm_handle_vblank(dev, 0);
		if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
			drm_handle_vblank(dev, 1);
	} else {
		if (stat & RADEON_CRTC_VBLANK_STAT)
			drm_handle_vblank(dev, 0);
		if (stat & RADEON_CRTC2_VBLANK_STAT)
			drm_handle_vblank(dev, 1);
	}
	return IRQ_HANDLED;
}
irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
{
	struct drm_device *dev = (struct drm_device *) arg;
	drm_radeon_private_t *dev_priv =
	    (drm_radeon_private_t *) dev->dev_private;
	u32 stat;
	u32 r500_disp_int;

	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
		return IRQ_NONE;

	stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int);
	if (!stat)
		return IRQ_NONE;

	stat &= dev_priv->irq_enable_reg;

	
	if (stat & RADEON_SW_INT_TEST)
		DRM_WAKEUP(&dev_priv->swi_queue);

	
	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
		if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
			drm_handle_vblank(dev, 0);
		if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
			drm_handle_vblank(dev, 1);
	} else {
		if (stat & RADEON_CRTC_VBLANK_STAT)
			drm_handle_vblank(dev, 0);
		if (stat & RADEON_CRTC2_VBLANK_STAT)
			drm_handle_vblank(dev, 1);
	}
	return IRQ_HANDLED;
}
Esempio n. 4
0
/* drm_dma.h hooks
*/
void DRM(driver_irq_preinstall)( drm_device_t *dev ) {
	drm_radeon_private_t *dev_priv =
		(drm_radeon_private_t *)dev->dev_private;

 	/* Disable *all* interrupts */
      	RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );

	/* Clear bits if they're already high */
	radeon_acknowledge_irqs( dev_priv );
}
Esempio n. 5
0
/* drm_dma.h hooks
*/
void radeon_driver_irq_preinstall(struct drm_device * dev)
{
	drm_radeon_private_t *dev_priv =
	    (drm_radeon_private_t *) dev->dev_private;

	/* Disable *all* interrupts */
	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);

	/* Clear bits if they're already high */
	radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
					   RADEON_CRTC_VBLANK_STAT |
					   RADEON_CRTC2_VBLANK_STAT));
}
Esempio n. 6
0
/* drm_dma.h hooks
*/
void radeon_driver_irq_preinstall(struct drm_device * dev)
{
	drm_radeon_private_t *dev_priv =
	    (drm_radeon_private_t *) dev->dev_private;
	u32 dummy;

	/* Disable *all* interrupts */
	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);

	/* Clear bits if they're already high */
	radeon_acknowledge_irqs(dev_priv, &dummy);
}
Esempio n. 7
0
irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
{
	struct drm_device *dev = (struct drm_device *) arg;
	drm_radeon_private_t *dev_priv =
	    (drm_radeon_private_t *) dev->dev_private;
	u32 stat;

	/* Only consider the bits we're interested in - others could be used
	 * outside the DRM
	 */
	stat = radeon_acknowledge_irqs(dev_priv, (RADEON_SW_INT_TEST_ACK |
						  RADEON_CRTC_VBLANK_STAT |
						  RADEON_CRTC2_VBLANK_STAT));
	if (!stat)
		return IRQ_NONE;

	stat &= dev_priv->irq_enable_reg;

	/* SW interrupt */
	if (stat & RADEON_SW_INT_TEST) {
		DRM_WAKEUP(&dev_priv->swi_queue);
	}

	/* VBLANK interrupt */
	if (stat & (RADEON_CRTC_VBLANK_STAT|RADEON_CRTC2_VBLANK_STAT)) {
		int vblank_crtc = dev_priv->vblank_crtc;

		if ((vblank_crtc &
		     (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) ==
		    (DRM_RADEON_VBLANK_CRTC1 | DRM_RADEON_VBLANK_CRTC2)) {
			if (stat & RADEON_CRTC_VBLANK_STAT)
				atomic_inc(&dev->vbl_received);
			if (stat & RADEON_CRTC2_VBLANK_STAT)
				atomic_inc(&dev->vbl_received2);
		} else if (((stat & RADEON_CRTC_VBLANK_STAT) &&
			   (vblank_crtc & DRM_RADEON_VBLANK_CRTC1)) ||
			   ((stat & RADEON_CRTC2_VBLANK_STAT) &&
			    (vblank_crtc & DRM_RADEON_VBLANK_CRTC2)))
			atomic_inc(&dev->vbl_received);

		DRM_WAKEUP(&dev->vbl_queue);
		drm_vbl_send_signals(dev);
	}

	return IRQ_HANDLED;
}
void radeon_driver_irq_preinstall(struct drm_device * dev)
{
	drm_radeon_private_t *dev_priv =
	    (drm_radeon_private_t *) dev->dev_private;
	u32 dummy;

	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
		return;

	
	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);

	
	radeon_acknowledge_irqs(dev_priv, &dummy);
}
Esempio n. 9
0
int radeon_wait_irq(drm_device_t *dev, int swi_nr)
{
  	drm_radeon_private_t *dev_priv = 
	   (drm_radeon_private_t *)dev->dev_private;
	int ret = 0;

 	if (RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr)  
 		return 0; 

	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;

	/* This is a hack to work around mysterious freezes on certain
	 * systems:
	 */ 
	radeon_acknowledge_irqs( dev_priv );

	DRM_WAIT_ON( ret, dev_priv->swi_queue, 3 * DRM_HZ, 
		     RADEON_READ( RADEON_LAST_SWI_REG ) >= swi_nr );

	return ret;
}
Esempio n. 10
0
static int radeon_driver_vblank_do_wait(struct drm_device * dev,
					unsigned int *sequence, int crtc)
{
	drm_radeon_private_t *dev_priv =
	    (drm_radeon_private_t *) dev->dev_private;
	unsigned int cur_vblank;
	int ret = 0;
	int ack = 0;
	atomic_t *counter;
	if (!dev_priv) {
		DRM_ERROR("called with no initialization\n");
		return -EINVAL;
	}

	if (crtc == DRM_RADEON_VBLANK_CRTC1) {
		counter = &dev->vbl_received;
		ack |= RADEON_CRTC_VBLANK_STAT;
	} else if (crtc == DRM_RADEON_VBLANK_CRTC2) {
		counter = &dev->vbl_received2;
		ack |= RADEON_CRTC2_VBLANK_STAT;
	} else
		return -EINVAL;

	radeon_acknowledge_irqs(dev_priv, ack);

	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;

	/* Assume that the user has missed the current sequence number
	 * by about a day rather than she wants to wait for years
	 * using vertical blanks...
	 */
	DRM_WAIT_ON(ret, dev->vbl_queue, 3 * DRM_HZ,
		    (((cur_vblank = atomic_read(counter))
		      - *sequence) <= (1 << 23)));

	*sequence = cur_vblank;

	return ret;
}
Esempio n. 11
0
irqreturn_t radeon_driver_irq_handler(DRM_IRQ_ARGS)
{
	struct drm_device *dev = (struct drm_device *) arg;
	drm_radeon_private_t *dev_priv =
	    (drm_radeon_private_t *) dev->dev_private;
	u32 stat;
	u32 r500_disp_int;
	u32 tmp;

	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600)
		return IRQ_NONE;

	/* Only consider the bits we're interested in - others could be used
	 * outside the DRM
	 */
	stat = radeon_acknowledge_irqs(dev_priv, &r500_disp_int);
	if (!stat)
		return IRQ_NONE;

	stat &= dev_priv->irq_enable_reg;

	/* SW interrupt */
	if (stat & RADEON_SW_INT_TEST)
		DRM_WAKEUP(&dev_priv->swi_queue);

	/* VBLANK interrupt */
	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
		if (r500_disp_int & R500_D1_VBLANK_INTERRUPT)
			drm_handle_vblank(dev, 0);
		if (r500_disp_int & R500_D2_VBLANK_INTERRUPT)
			drm_handle_vblank(dev, 1);
	} else {
		if (stat & RADEON_CRTC_VBLANK_STAT)
			drm_handle_vblank(dev, 0);
		if (stat & RADEON_CRTC2_VBLANK_STAT)
			drm_handle_vblank(dev, 1);
	}
	if (dev->msi_enabled) {
		switch(dev_priv->flags & RADEON_FAMILY_MASK) {
			case CHIP_RS400:
			case CHIP_RS480:
				tmp = RADEON_READ(RADEON_AIC_CNTL) &
				    ~RS400_MSI_REARM;
				RADEON_WRITE(RADEON_AIC_CNTL, tmp);
				RADEON_WRITE(RADEON_AIC_CNTL,
				    tmp | RS400_MSI_REARM);
				break;
			case CHIP_RS600:
			case CHIP_RS690:
			case CHIP_RS740:
				tmp = RADEON_READ(RADEON_BUS_CNTL) &
				    ~RS600_MSI_REARM;
				RADEON_WRITE(RADEON_BUS_CNTL, tmp);
				RADEON_WRITE(RADEON_BUS_CNTL, tmp |
				    RS600_MSI_REARM);
				break;
			 default:
				tmp = RADEON_READ(RADEON_MSI_REARM_EN) &
				    ~RV370_MSI_REARM_EN;
				RADEON_WRITE(RADEON_MSI_REARM_EN, tmp);
				RADEON_WRITE(RADEON_MSI_REARM_EN,
				    tmp | RV370_MSI_REARM_EN);
				break;
		}
	}
	return IRQ_HANDLED;
}