コード例 #1
0
ファイル: mga_warp.c プロジェクト: JBTech/ralink_rt5350
int mga_warp_init( drm_mga_private_t *dev_priv )
{
	u32 wmisc;

	/* FIXME: Get rid of these damned magic numbers...
	 */
	switch ( dev_priv->chipset ) {
	case MGA_CARD_TYPE_G400:
		MGA_WRITE( MGA_WIADDR2, MGA_WMODE_SUSPEND );
		MGA_WRITE( MGA_WGETMSB, 0x00000E00 );
		MGA_WRITE( MGA_WVRTXSZ, 0x00001807 );
		MGA_WRITE( MGA_WACCEPTSEQ, 0x18000000 );
		break;
	case MGA_CARD_TYPE_G200:
		MGA_WRITE( MGA_WIADDR, MGA_WMODE_SUSPEND );
		MGA_WRITE( MGA_WGETMSB, 0x1606 );
		MGA_WRITE( MGA_WVRTXSZ, 7 );
		break;
	default:
		return -EINVAL;
	}

	MGA_WRITE( MGA_WMISC, (MGA_WUCODECACHE_ENABLE |
			       MGA_WMASTER_ENABLE |
			       MGA_WCACHEFLUSH_ENABLE) );
	wmisc = MGA_READ( MGA_WMISC );
	if ( wmisc != WMISC_EXPECTED ) {
		DRM_ERROR( "WARP engine config failed! 0x%x != 0x%x\n",
			   wmisc, WMISC_EXPECTED );
		return -EINVAL;
	}

	return 0;
}
コード例 #2
0
irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
{
	drm_device_t *dev = (drm_device_t *) arg;
	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
	int status;
	int handled = 0;

	status = MGA_READ(MGA_STATUS);

	/* VBLANK interrupt */
	if (status & MGA_VLINEPEN) {
		MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
		atomic_inc(&dev->vbl_received);
		DRM_WAKEUP(&dev->vbl_queue);
		drm_vbl_send_signals(dev);
		handled = 1;
	}

	/* SOFTRAP interrupt */
	if (status & MGA_SOFTRAPEN) {
		const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
		const u32 prim_end   = MGA_READ(MGA_PRIMEND);


		MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);

		/* In addition to clearing the interrupt-pending bit, we
		 * have to write to MGA_PRIMEND to re-start the DMA operation.
		 */
		if ( (prim_start & ~0x03) != (prim_end & ~0x03) ) {
			MGA_WRITE(MGA_PRIMEND, prim_end);
		}

		atomic_inc(&dev_priv->last_fence_retired);
		DRM_WAKEUP(&dev_priv->fence_queue);
		handled = 1;
	}

	if ( handled ) {
		return IRQ_HANDLED;
	}
	return IRQ_NONE;
}
コード例 #3
0
irqreturn_t mga_driver_irq_handler(DRM_IRQ_ARGS)
{
	struct drm_device *dev = (struct drm_device *) arg;
	drm_mga_private_t *dev_priv = (drm_mga_private_t *) dev->dev_private;
	int status;
	int handled = 0;

	status = MGA_READ(MGA_STATUS);

	
	if (status & MGA_VLINEPEN) {
		MGA_WRITE(MGA_ICLEAR, MGA_VLINEICLR);
		atomic_inc(&dev_priv->vbl_received);
		drm_handle_vblank(dev, 0);
		handled = 1;
	}

	
	if (status & MGA_SOFTRAPEN) {
		const u32 prim_start = MGA_READ(MGA_PRIMADDRESS);
		const u32 prim_end = MGA_READ(MGA_PRIMEND);


		MGA_WRITE(MGA_ICLEAR, MGA_SOFTRAPICLR);

		if ((prim_start & ~0x03) != (prim_end & ~0x03))
			MGA_WRITE(MGA_PRIMEND, prim_end);

		atomic_inc(&dev_priv->last_fence_retired);
		DRM_WAKEUP(&dev_priv->fence_queue);
		handled = 1;
	}

	if (handled)
		return IRQ_HANDLED;
	return IRQ_NONE;
}
コード例 #4
0
ファイル: mga_dma.c プロジェクト: JBTech/ralink_rt5350
int mga_do_dma_idle( drm_mga_private_t *dev_priv )
{
	u32 status = 0;
	int i;
	DRM_DEBUG( "\n" );

	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
		status = MGA_READ( MGA_STATUS ) & MGA_DMA_IDLE_MASK;
		if ( status == MGA_ENDPRDMASTS ) return 0;
		udelay( 1 );
	}

#if MGA_DMA_DEBUG
	DRM_ERROR( "failed! status=0x%08x\n", status );
#endif
	return -EBUSY;
}
コード例 #5
0
ファイル: mga_dma.c プロジェクト: JBTech/ralink_rt5350
static void mga_freelist_print( drm_device_t *dev )
{
	drm_mga_private_t *dev_priv = dev->dev_private;
	drm_mga_freelist_t *entry;

	DRM_INFO( "\n" );
	DRM_INFO( "current dispatch: last=0x%x done=0x%x\n",
		  dev_priv->sarea_priv->last_dispatch,
		  (unsigned int)(MGA_READ( MGA_PRIMADDRESS ) -
				 dev_priv->primary->offset) );
	DRM_INFO( "current freelist:\n" );

	for ( entry = dev_priv->head->next ; entry ; entry = entry->next ) {
		DRM_INFO( "   %p   idx=%2d  age=0x%x 0x%06lx\n",
			  entry, entry->buf->idx, entry->age.head,
			  entry->age.head - dev_priv->primary->offset );
	}
	DRM_INFO( "\n" );
}
コード例 #6
0
ファイル: mga_dma.c プロジェクト: JBTech/ralink_rt5350
void mga_do_dma_wrap_start( drm_mga_private_t *dev_priv )
{
	drm_mga_primary_buffer_t *primary = &dev_priv->prim;
	u32 head, tail;
	DMA_LOCALS;
	DRM_DEBUG( "\n" );

	BEGIN_DMA_WRAP();

	DMA_BLOCK( MGA_DMAPAD,	0x00000000,
		   MGA_DMAPAD,	0x00000000,
		   MGA_DMAPAD,	0x00000000,
		   MGA_DMAPAD,	0x00000000 );

	ADVANCE_DMA();

	tail = primary->tail + dev_priv->primary->offset;

	primary->tail = 0;
	primary->last_flush = 0;
	primary->last_wrap++;

	head = MGA_READ( MGA_PRIMADDRESS );

	if ( head == dev_priv->primary->offset ) {
		primary->space = primary->size;
	} else {
		primary->space = head - dev_priv->primary->offset;
	}

	DRM_DEBUG( "   head = 0x%06lx\n",
		  head - dev_priv->primary->offset );
	DRM_DEBUG( "   tail = 0x%06x\n", primary->tail );
	DRM_DEBUG( "   wrap = %d\n", primary->last_wrap );
	DRM_DEBUG( "  space = 0x%06x\n", primary->space );

	mga_flush_write_combine();
	MGA_WRITE( MGA_PRIMEND, tail | MGA_PAGPXFER );

	set_bit( 0, &primary->wrapped );
	DRM_DEBUG( "done.\n" );
}
コード例 #7
0
ファイル: mga_dma.c プロジェクト: JBTech/ralink_rt5350
int mga_do_wait_for_idle( drm_mga_private_t *dev_priv )
{
	u32 status = 0;
	int i;
	DRM_DEBUG( "\n" );

	for ( i = 0 ; i < dev_priv->usec_timeout ; i++ ) {
		status = MGA_READ( MGA_STATUS ) & MGA_ENGINE_IDLE_MASK;
		if ( status == MGA_ENDPRDMASTS ) {
			MGA_WRITE8( MGA_CRTC_INDEX, 0 );
			return 0;
		}
		udelay( 1 );
	}

#if MGA_DMA_DEBUG
	DRM_ERROR( "failed!\n" );
	DRM_INFO( "   status=0x%08x\n", status );
#endif
	return -EBUSY;
}
コード例 #8
0
ファイル: mgaioctl.c プロジェクト: dikerex/theqvd
/*
 * Copy the back buffer to the front buffer.
 */
void mgaSwapBuffers(Display *dpy, void *drawablePrivate)
{
   __DRIdrawablePrivate *dPriv = (__DRIdrawablePrivate *) drawablePrivate;
   mgaContextPtr mmesa;
   XF86DRIClipRectPtr pbox;
   GLint nbox;
   GLint ret, wait = 0;
   GLint i;
   GLuint last_frame, last_wrap;

   assert(dPriv);
   assert(dPriv->driContextPriv);
   assert(dPriv->driContextPriv->driverPrivate);

   mmesa = (mgaContextPtr) dPriv->driContextPriv->driverPrivate;

   FLUSH_BATCH( mmesa );

   mgaWaitForVBlank( mmesa );

   LOCK_HARDWARE( mmesa );

   last_frame = mmesa->sarea->last_frame.head;
   last_wrap = mmesa->sarea->last_frame.wrap;

   /* FIXME: Add a timeout to this loop...
    */
   while ( 1 ) {
      if ( last_wrap < mmesa->sarea->last_wrap ||
	   ( last_wrap == mmesa->sarea->last_wrap &&
	     last_frame <= (MGA_READ( MGAREG_PRIMADDRESS ) -
			    mmesa->primary_offset) ) ) {
	 break;
      }
      if ( 0 ) {
	 wait++;
	 fprintf( stderr, "   last: head=0x%06x wrap=%d\n",
		  last_frame, last_wrap );
	 fprintf( stderr, "   head: head=0x%06lx wrap=%d\n",
		  (long)(MGA_READ( MGAREG_PRIMADDRESS ) - mmesa->primary_offset),
		  mmesa->sarea->last_wrap );
      }
      UPDATE_LOCK( mmesa, DRM_LOCK_FLUSH );

      for ( i = 0 ; i < 1024 ; i++ ) {
	 /* Don't just hammer the register... */
      }
   }
   if ( wait )
      fprintf( stderr, "\n" );

   /* Use the frontbuffer cliprects
    */
   if (mmesa->dirty_cliprects & MGA_FRONT)
      mgaUpdateRects( mmesa, MGA_FRONT );


   pbox = dPriv->pClipRects;
   nbox = dPriv->numClipRects;

   for (i = 0 ; i < nbox ; )
   {
      int nr = MIN2(i + MGA_NR_SAREA_CLIPRECTS, dPriv->numClipRects);
      XF86DRIClipRectPtr b = mmesa->sarea->boxes;

      mmesa->sarea->nbox = nr - i;

      for ( ; i < nr ; i++)
	 *b++ = pbox[i];

      if (0)
	 fprintf(stderr, "DRM_IOCTL_MGA_SWAP\n");

      ret = drmCommandNone( mmesa->driFd, DRM_MGA_SWAP );
      if ( ret ) {
	 printf("send swap retcode = %d\n", ret);
	 exit(1);
      }
   }

   UNLOCK_HARDWARE( mmesa );

   mmesa->dirty |= MGA_UPLOAD_CLIPRECTS;
}