Ejemplo n.º 1
0
static int
pxa3xx_gcu_wait_free(struct pxa3xx_gcu_priv *priv)
{
	int ret = 0;

	QDUMP("Waiting for free...");

	/* Does not need to be atomic. There's a lock in user space,
	 * but anyhow, this is just for statistics. */
	priv->shared->num_wait_free++;

	while (!priv->free) {
		u32 rbexhr = gc_readl(priv, REG_GCRBEXHR);

		ret = wait_event_interruptible_timeout(priv->wait_free,
						       priv->free, HZ*4);

		if (ret < 0)
			break;

		if (ret > 0)
			continue;

		if (gc_readl(priv, REG_GCRBEXHR) == rbexhr) {
			QERROR("TIMEOUT");
			ret = -ETIMEDOUT;
			break;
		}
	}

	QDUMP("done");

	return ret;
}
Ejemplo n.º 2
0
static int
pxa3xx_gcu_wait_idle(struct pxa3xx_gcu_priv *priv)
{
	int ret = 0;

	QDUMP("Waiting for idle...");

	/* Does not need to be atomic. There's a lock in user space,
	 * but anyhow, this is just for statistics. */
	priv->shared->num_wait_idle++;

	while (priv->shared->hw_running) {
		int num = priv->shared->num_interrupts;
		u32 rbexhr = gc_readl(priv, REG_GCRBEXHR);

		ret = wait_event_interruptible_timeout(priv->wait_idle,
					!priv->shared->hw_running, HZ*4);

		if (ret != 0)
			break;

		if (gc_readl(priv, REG_GCRBEXHR) == rbexhr &&
		    priv->shared->num_interrupts == num) {
			QERROR("TIMEOUT");
			ret = -ETIMEDOUT;
			break;
		}
	}

	QDUMP("done");

	return ret;
}
Ejemplo n.º 3
0
static int
sh7722_wait_next( SH772xGfxSharedArea *shared )
{
     int ret;

     QDUMP( "Waiting....." );

     /* Does not need to be atomic. There's a lock in user space,
      * but anyhow, this is just for statistics. */
     shared->num_wait_next++;

     ret = wait_event_interruptible_timeout( wait_next, !shared->hw_running ||
                                             shared->next_start == shared->next_end, 42*HZ );
     if (!ret) {
          printk( KERN_ERR "%s: TIMEOUT! (%srunning, hw %d-%d, next %d-%d - %svalid, "
                           "STATUS 0x%08x, INT_STATUS 0x%08x)\n",
                  __FUNCTION__,
                  shared->hw_running ? "" : "not ",
                  shared->hw_start,
                  shared->hw_end,
                  shared->next_start,
                  shared->next_end,
                  shared->next_valid ? "" : "not ",
                  BEM_HC_STATUS, BEM_HC_INT_STATUS );
     }

     QDUMP( "........done" );

     return (ret > 0) ? 0 : (ret < 0) ? ret : -ETIMEDOUT;
}
Ejemplo n.º 4
0
static irqreturn_t
pxa3xx_gcu_handle_irq(int irq, void *ctx)
{
	struct pxa3xx_gcu_priv *priv = ctx;
	struct pxa3xx_gcu_shared *shared = priv->shared;
	u32 status = gc_readl(priv, REG_GCISCR) & IE_ALL;

	QDUMP("-Interrupt");

	if (!status)
		return IRQ_NONE;

	spin_lock(&priv->spinlock);
	shared->num_interrupts++;

	if (status & IE_EEOB) {
		QDUMP(" [EEOB]");

		flush_running(priv);
		wake_up_all(&priv->wait_free);

		if (priv->ready) {
			run_ready(priv);
		} else {
			/* There is no more data prepared by the userspace.
			 * Set hw_running = 0 and wait for the next userspace
			 * kick-off */
			shared->num_idle++;
			shared->hw_running = 0;

			QDUMP(" '-> Idle.");

			/* set ring buffer length to zero */
			gc_writel(priv, REG_GCRBLR, 0);

			wake_up_all(&priv->wait_idle);
		}

		shared->num_done++;
	} else {
		QERROR(" [???]");
		dump_whole_state(priv);
	}

	/* Clear the interrupt */
	gc_writel(priv, REG_GCISCR, status);
	spin_unlock(&priv->spinlock);

	return IRQ_HANDLED;
}
Ejemplo n.º 5
0
static void
run_ready(struct pxa3xx_gcu_priv *priv)
{
	unsigned int num = 0;
	struct pxa3xx_gcu_shared *shared = priv->shared;
	struct pxa3xx_gcu_batch	*ready = priv->ready;

	QDUMP("Start");

	BUG_ON(!ready);

	shared->buffer[num++] = 0x05000000;

	while (ready) {
		shared->buffer[num++] = 0x00000001;
		shared->buffer[num++] = ready->phys;
		ready = ready->next;
	}

	shared->buffer[num++] = 0x05000000;
	priv->running = priv->ready;
	priv->ready = priv->ready_last = NULL;
	gc_writel(priv, REG_GCRBLR, 0);
	shared->hw_running = 1;

	/* ring base address */
	gc_writel(priv, REG_GCRBBR, shared->buffer_phys);

	/* ring tail address */
	gc_writel(priv, REG_GCRBTR, shared->buffer_phys + num * 4);

	/* ring length */
	gc_writel(priv, REG_GCRBLR, ((num + 63) & ~63) * 4);
}
Ejemplo n.º 6
0
static void
pxa3xx_gcu_reset(struct pxa3xx_gcu_priv *priv)
{
	QDUMP("RESET");

	/* disable interrupts */
	gc_writel(priv, REG_GCIECR, 0);

	/* reset hardware */
	gc_writel(priv, REG_GCCR, GCCR_ABORT);
	gc_writel(priv, REG_GCCR, 0);

	memset(priv->shared, 0, SHARED_SIZE);
	priv->shared->buffer_phys = priv->shared_phys;
	priv->shared->magic = PXA3XX_GCU_SHARED_MAGIC;

	do_gettimeofday(&priv->base_time);

	/* set up the ring buffer pointers */
	gc_writel(priv, REG_GCRBLR, 0);
	gc_writel(priv, REG_GCRBBR, priv->shared_phys);
	gc_writel(priv, REG_GCRBTR, priv->shared_phys);

	/* enable all IRQs except EOB */
	gc_writel(priv, REG_GCIECR, IE_ALL & ~IE_EOB);
}
Ejemplo n.º 7
0
void
DHMWindow::onAddDAS(const QString &das)
{
    QDUMP(das);
    if (dasset_.find(das) != dasset_.end())
    {
        messages_->append(QString("%1 found in DHM list").arg(das));
        return;
    }
    daslist_->addItem(das);
    dasset_.insert(das);
    messages_->append(QString("%1 inserted into DHM list").arg(das));
}
Ejemplo n.º 8
0
static void
dump_whole_state(struct pxa3xx_gcu_priv *priv)
{
	struct pxa3xx_gcu_shared *sh = priv->shared;
	u32 base = gc_readl(priv, REG_GCRBBR);

	QDUMP("DUMP");

	printk(KERN_DEBUG "== PXA3XX-GCU DUMP ==\n"
		"%s, STATUS 0x%02lx, B 0x%08lx [%ld], E %5ld, H %5ld, T %5ld\n",
		sh->hw_running ? "running" : "idle   ",
		gc_readl(priv, REG_GCISCR),
		gc_readl(priv, REG_GCRBBR),
		gc_readl(priv, REG_GCRBLR),
		(gc_readl(priv, REG_GCRBEXHR) - base) / 4,
		(gc_readl(priv, REG_GCRBHR) - base) / 4,
		(gc_readl(priv, REG_GCRBTR) - base) / 4);
}
Ejemplo n.º 9
0
void
DHMWindow::onRemoveDAS(const QString &das)
{
    QDUMP(das);
    if (dasset_.find(das) == dasset_.end())
    {
        messages_->append(QString("%1 NOT found in DHM list").arg(das));
        return;
    }
    QList<QListWidgetItem*> removelist = daslist_->findItems(das, Qt::MatchExactly);
    QList<QListWidgetItem*>::Iterator rit = removelist.begin();
    QList<QListWidgetItem*>::Iterator ritend = removelist.end();
    for ( ; rit != ritend; ++rit)
    {
        int row = daslist_->row(*rit);
        daslist_->takeItem(row);
        dasset_.remove(das);
    }
    messages_->append(QString("%1 removed from DHM list").arg(das));
}
Ejemplo n.º 10
0
static int
sh7722_reset( SH772xGfxSharedArea *shared )
{
     int i;

     do_gettimeofday( &base_time );

     QPRINT( "Resetting hardware..." );

     BEM_HC_CLOCK = 0;
     for (i=0; i<30000; i++);
     BEM_HC_CLOCK = 0x1111;

     BEM_HC_RESET = 0x1111;
     for (i=0; i<30000; i++);
     BEM_HC_RESET = 0;


     QPRINT( "Initializing shared area..." );

     memset( (void*) shared, 0, sizeof(SH772xGfxSharedArea) );

     shared->buffer_phys = virt_to_phys(&shared->buffer[0]);
     shared->jpeg_phys   = virt_to_phys(jpeg_area);
     shared->magic       = SH7722GFX_SHARED_MAGIC;


     QPRINT( "Clearing interrupts..." );

     BEM_HC_INT_CLEAR = 0x111111;
     BEM_HC_INT_MASK  = 0x110011;

     BEM_HC_CACHE_FLUSH = 0;

     QDUMP( "Ready" );

     return 0;
}
Ejemplo n.º 11
0
void
DHMWindow::onStatusMessage(const QString &message)
{
    QDUMP(message);
}
Ejemplo n.º 12
0
static irqreturn_t
sh7722_tdg_irq( int irq, void *ctx )
{
     SH772xGfxSharedArea *shared = ctx;
     u32                  status = BEM_HC_INT_STATUS;

     if (! (status & 0x111111)) {
#ifndef SH7722GFX_IRQ_POLLER
          printk( KERN_WARNING "%s: bogus interrupt, INT_STATUS 0x%08x!\n", __FUNCTION__, status );
#endif
          return IRQ_NONE;
     }

     if (status & ~0x100)
          QDUMP( "-Interrupt" );

     if (status & ~0x101100)
          printk( KERN_ERR "%s: error! INT_STATUS 0x%08x!\n", __FUNCTION__, status );

     shared->num_interrupts++;

     /* Clear the interrupt. */
     BEM_HC_INT_CLEAR = status;

     if (status & 0x100010) {
          if (!shared->hw_running)
               printk( KERN_WARNING "%s: hw not running? INT_STATUS 0x%08x!\n", __FUNCTION__, status );

          if (status & 0x10) {
               printk( KERN_ERR "%s: RUNAWAY! (%srunning, hw %d-%d, next %d-%d - %svalid, "
                                "STATUS 0x%08x, INT_STATUS 0x%08x)\n",
                       __FUNCTION__,
                       shared->hw_running ? "" : "not ",
                       shared->hw_start,
                       shared->hw_end,
                       shared->next_start,
                       shared->next_end,
                       shared->next_valid ? "" : "not ",
                       BEM_HC_STATUS, status );

               BEM_HC_RESET = 0x1111;
          }

          /* Next valid means user space is not in the process of extending the buffer. */
          if (shared->next_valid && shared->next_start != shared->next_end) {
               shared->hw_start = shared->next_start;
               shared->hw_end   = shared->next_end;

               shared->next_start = shared->next_end = (shared->hw_end + 1 + 3) & ~3;
               shared->next_valid = 0;

               shared->num_words += shared->hw_end - shared->hw_start;

               shared->num_starts++;

               QDUMP( " '-> Start!" );

               BEM_HC_DMA_ADR   = shared->buffer_phys + shared->hw_start*4;
               BEM_HC_DMA_START = 1;

               wake_up_all( &wait_next );
          }
          else {
               shared->num_idle++;

               QDUMP( " '-> Idle." );

               BEM_PE_CACHE = 1;

               shared->hw_running = 0;

               wake_up_all( &wait_next );
               wake_up_all( &wait_idle );
          }

          shared->num_done++;
     }

     return IRQ_HANDLED;
}