示例#1
0
int
radeondrm_activate(struct device *arg, int act)
{
	struct drm_radeon_private *dev_priv = (struct drm_radeon_private *)arg;
	struct drm_device	*dev = (struct drm_device *)dev_priv->drmdev;

	switch (act) {
	case DVACT_SUSPEND:
		/* Interrupts still not supported on r600 */
		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600 ||
		    dev->irq_enabled == 0)
			break;
		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
			RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
		RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
		break;
	case DVACT_RESUME:
		/* Interrupts still not supported on r600 */
		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600 ||
		    dev->irq_enabled == 0)
			break;
		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
			RADEON_WRITE(R500_DxMODE_INT_MASK,
			    dev_priv->r500_disp_irq_reg);
		RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
		break;
	}

	return (0);
}
示例#2
0
static u32 radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv, u32 *r500_disp_int)
{
	u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS);
	u32 irq_mask = RADEON_SW_INT_TEST;

	*r500_disp_int = 0;
	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600) {
		/* vbl interrupts in a different place */

		if (irqs & R500_DISPLAY_INT_STATUS) {
			/* if a display interrupt */
			u32 disp_irq;

			disp_irq = RADEON_READ(R500_DISP_INTERRUPT_STATUS);

			*r500_disp_int = disp_irq;
			if (disp_irq & R500_D1_VBLANK_INTERRUPT)
				RADEON_WRITE(R500_D1MODE_VBLANK_STATUS, R500_VBLANK_ACK);
			if (disp_irq & R500_D2_VBLANK_INTERRUPT)
				RADEON_WRITE(R500_D2MODE_VBLANK_STATUS, R500_VBLANK_ACK);
		}
		irq_mask |= R500_DISPLAY_INT_STATUS;
	} else
		irq_mask |= RADEON_CRTC_VBLANK_STAT | RADEON_CRTC2_VBLANK_STAT;

	irqs &=	irq_mask;

	if (irqs)
		RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);

	return irqs;
}
static u32 RS690_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
	u32 ret;
	RADEON_WRITE(RS690_MC_INDEX, (addr & RS690_MC_INDEX_MASK));
	ret = RADEON_READ(RS690_MC_DATA);
	RADEON_WRITE(RS690_MC_INDEX, RS690_MC_INDEX_MASK);
	return ret;
}
static u32 RS480_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
	u32 ret;
	RADEON_WRITE(RS480_NB_MC_INDEX, addr & 0xff);
	ret = RADEON_READ(RS480_NB_MC_DATA);
	RADEON_WRITE(RS480_NB_MC_INDEX, 0xff);
	return ret;
}
static u32 R500_READ_MCIND(drm_radeon_private_t *dev_priv, int addr)
{
	u32 ret;
	RADEON_WRITE(R520_MC_IND_INDEX, 0x7f0000 | (addr & 0xff));
	ret = RADEON_READ(R520_MC_IND_DATA);
	RADEON_WRITE(R520_MC_IND_INDEX, 0);
	return ret;
}
示例#6
0
void radeon_driver_irq_uninstall(struct drm_device * dev)
{
	drm_radeon_private_t *dev_priv =
	    (drm_radeon_private_t *) dev->dev_private;
	if (!dev_priv)
		return;

	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS690)
		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
	/* Disable *all* interrupts */
	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
}
示例#7
0
static int radeon_suspend(struct drm_device *dev, pm_message_t state)
{
	drm_radeon_private_t *dev_priv = dev->dev_private;

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

	/* Disable *all* interrupts */
	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
		RADEON_WRITE(R500_DxMODE_INT_MASK, 0);
	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
	return 0;
}
示例#8
0
static int radeon_resume(struct drm_device *dev)
{
	drm_radeon_private_t *dev_priv = dev->dev_private;

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

	/* Restore interrupt registers */
	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_RS600)
		RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
	RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
	return 0;
}
示例#9
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);
}
static int radeon_do_pixcache_flush(drm_radeon_private_t * dev_priv)
{
	u32 tmp;
	int i;

	dev_priv->stats.boxes |= RADEON_BOX_WAIT_IDLE;

	if ((dev_priv->flags & RADEON_FAMILY_MASK) <= CHIP_RV280) {
		tmp = RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT);
		tmp |= RADEON_RB3D_DC_FLUSH_ALL;
		RADEON_WRITE(RADEON_RB3D_DSTCACHE_CTLSTAT, tmp);

		for (i = 0; i < dev_priv->usec_timeout; i++) {
			if (!(RADEON_READ(RADEON_RB3D_DSTCACHE_CTLSTAT)
			      & RADEON_RB3D_DC_BUSY)) {
				return 0;
			}
			DRM_UDELAY(1);
		}
	} else {
		/* don't flush or purge cache here or lockup */
		return 0;
	}

#if RADEON_FIFO_DEBUG
	DRM_ERROR("failed!\n");
	radeon_status(dev_priv);
#endif
	return -EBUSY;
}
示例#11
0
文件: radeon_irq.c 项目: MarginC/kame
static __inline__ void radeon_acknowledge_irqs(drm_radeon_private_t *dev_priv)
{
	u32 tmp = RADEON_READ( RADEON_GEN_INT_STATUS )
		& (RADEON_SW_INT_TEST_ACK | RADEON_CRTC_VBLANK_STAT);
	if (tmp)
		RADEON_WRITE( RADEON_GEN_INT_STATUS, tmp );
}
示例#12
0
文件: radeon_irq.c 项目: MarginC/kame
void DRM(dma_service)( DRM_IRQ_ARGS )
{
	drm_device_t *dev = (drm_device_t *) 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_READ(RADEON_GEN_INT_STATUS)
	     & (RADEON_SW_INT_TEST | RADEON_CRTC_VBLANK_STAT);
	if (!stat)
		return;

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

	/* VBLANK interrupt */
	if (stat & RADEON_CRTC_VBLANK_STAT) {
		atomic_inc(&dev->vbl_received);
		DRM_WAKEUP(&dev->vbl_queue);
		DRM(vbl_send_signals)( dev );
	}

	/* Acknowledge interrupts we handle */
	RADEON_WRITE(RADEON_GEN_INT_STATUS, stat);
}
示例#13
0
static __inline__ u32 radeon_acknowledge_irqs(drm_radeon_private_t * dev_priv,
					      u32 mask)
{
	u32 irqs = RADEON_READ(RADEON_GEN_INT_STATUS) & mask;
	if (irqs)
		RADEON_WRITE(RADEON_GEN_INT_STATUS, irqs);
	return irqs;
}
示例#14
0
文件: radeon_irq.c 项目: MarginC/kame
void DRM(driver_irq_uninstall)( drm_device_t *dev ) {
	drm_radeon_private_t *dev_priv =
		(drm_radeon_private_t *)dev->dev_private;
	if ( dev_priv ) {
		/* Disable *all* interrupts */
		RADEON_WRITE( RADEON_GEN_INT_CNTL, 0 );
	}
}
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);
}
示例#16
0
文件: radeon_irq.c 项目: MarginC/kame
/* 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 );
}
示例#17
0
static void r500_vbl_irq_set_state(struct drm_device *dev, u32 mask, int state)
{
	drm_radeon_private_t *dev_priv = dev->dev_private;

	if (state)
		dev_priv->r500_disp_irq_reg |= mask;
	else
		dev_priv->r500_disp_irq_reg &= ~mask;

	RADEON_WRITE(R500_DxMODE_INT_MASK, dev_priv->r500_disp_irq_reg);
}
示例#18
0
void radeon_irq_set_state(struct drm_device *dev, u32 mask, int state)
{
	drm_radeon_private_t *dev_priv = dev->dev_private;

	if (state)
		dev_priv->irq_enable_reg |= mask;
	else
		dev_priv->irq_enable_reg &= ~mask;

	RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
}
static void radeon_write_fb_location(drm_radeon_private_t *dev_priv, u32 fb_loc)
{
	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515)
		R500_WRITE_MCIND(RV515_MC_FB_LOCATION, fb_loc);
	else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690)
		RS690_WRITE_MCIND(RS690_MC_FB_LOCATION, fb_loc);
	else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515)
		R500_WRITE_MCIND(R520_MC_FB_LOCATION, fb_loc);
	else
		RADEON_WRITE(RADEON_MC_FB_LOCATION, fb_loc);
}
示例#20
0
文件: radeon_irq.c 项目: MarginC/kame
void DRM(driver_irq_postinstall)( drm_device_t *dev ) {
	drm_radeon_private_t *dev_priv =
		(drm_radeon_private_t *)dev->dev_private;

   	atomic_set(&dev_priv->swi_emitted, 0);
	DRM_INIT_WAITQUEUE( &dev_priv->swi_queue );

	/* Turn on SW and VBL ints */
   	RADEON_WRITE( RADEON_GEN_INT_CNTL,
		      RADEON_CRTC_VBLANK_MASK |	
		      RADEON_SW_INT_ENABLE );
}
示例#21
0
void radeon_driver_irq_uninstall(struct drm_device * dev)
{
	drm_radeon_private_t *dev_priv =
	    (drm_radeon_private_t *) dev->dev_private;
	if (!dev_priv)
		return;

	dev_priv->irq_enabled = 0;

	/* Disable *all* interrupts */
	RADEON_WRITE(RADEON_GEN_INT_CNTL, 0);
}
示例#22
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));
}
static void radeon_write_agp_base(drm_radeon_private_t *dev_priv, u64 agp_base)
{
	u32 agp_base_hi = upper_32_bits(agp_base);
	u32 agp_base_lo = agp_base & 0xffffffff;

	if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RV515) {
		R500_WRITE_MCIND(RV515_MC_AGP_BASE, agp_base_lo);
		R500_WRITE_MCIND(RV515_MC_AGP_BASE_2, agp_base_hi);
	} else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS690) {
		RS690_WRITE_MCIND(RS690_MC_AGP_BASE, agp_base_lo);
		RS690_WRITE_MCIND(RS690_MC_AGP_BASE_2, agp_base_hi);
	} else if ((dev_priv->flags & RADEON_FAMILY_MASK) > CHIP_RV515) {
		R500_WRITE_MCIND(R520_MC_AGP_BASE, agp_base_lo);
		R500_WRITE_MCIND(R520_MC_AGP_BASE_2, agp_base_hi);
	} else if ((dev_priv->flags & RADEON_FAMILY_MASK) == CHIP_RS480) {
		RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo);
		RADEON_WRITE(RS480_AGP_BASE_2, 0);
	} else {
		RADEON_WRITE(RADEON_AGP_BASE, agp_base_lo);
		if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R200)
			RADEON_WRITE(RADEON_AGP_BASE_2, agp_base_hi);
	}
}
示例#24
0
static void radeon_enable_interrupt(struct drm_device *dev)
{
	drm_radeon_private_t *dev_priv = (drm_radeon_private_t *) dev->dev_private;

	dev_priv->irq_enable_reg = RADEON_SW_INT_ENABLE;
	if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC1)
		dev_priv->irq_enable_reg |= RADEON_CRTC_VBLANK_MASK;

	if (dev_priv->vblank_crtc & DRM_RADEON_VBLANK_CRTC2)
		dev_priv->irq_enable_reg |= RADEON_CRTC2_VBLANK_MASK;

	RADEON_WRITE(RADEON_GEN_INT_CNTL, dev_priv->irq_enable_reg);
	dev_priv->irq_enabled = 1;
}
示例#25
0
void
radeondrm_commit_ring(struct drm_radeon_private *dev_priv)
{
	int		 i, tail_aligned, num_p2;
	u_int32_t	*ring;

	/* check if the ring is padded out to 16-dword alignment */

	tail_aligned = dev_priv->ring.tail & (RADEON_RING_ALIGN - 1);
	if (tail_aligned) {
		num_p2 = RADEON_RING_ALIGN - tail_aligned;

		ring = dev_priv->ring.start;
		/* pad with some CP_PACKET2 */
		for (i = 0; i < num_p2; i++)
			ring[dev_priv->ring.tail + i] = CP_PACKET2();

		dev_priv->ring.tail += i;
		dev_priv->ring.space -= num_p2;
		
	}
	dev_priv->ring.tail &= dev_priv->ring.tail_mask;
	/* XXX 128byte aligned stuff */
	/* flush write combining buffer and writes to ring */
	DRM_MEMORYBARRIER();
	radeondrm_get_ring_head(dev_priv);
	if ((dev_priv->flags & RADEON_FAMILY_MASK) >= CHIP_R600) {
		RADEON_WRITE(R600_CP_RB_WPTR, dev_priv->ring.tail);
		/* read from PCI bus to ensure correct posting */
		RADEON_READ(R600_CP_RB_RPTR);
	} else {
		RADEON_WRITE(RADEON_CP_RB_WPTR, dev_priv->ring.tail);
		/* read from PCI bus to ensure correct posting */
		RADEON_READ(RADEON_CP_RB_RPTR);
	}
}
示例#26
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;
}