static int fimg2d_sysmmu_fault_handler(enum S5P_SYSMMU_INTERRUPT_TYPE itype,
		unsigned long pgtable_base, unsigned long fault_addr)
{
	struct fimg2d_bltcmd *cmd;

	if (itype == SYSMMU_PAGEFAULT) {
		printk(KERN_ERR "[%s] sysmmu page fault(0x%lx), pgd(0x%lx)\n",
				__func__, fault_addr, pgtable_base);
	} else {
		printk(KERN_ERR "[%s] sysmmu interrupt "
				"type(%d) pgd(0x%lx) addr(0x%lx)\n",
				__func__, itype, pgtable_base, fault_addr);
	}

	cmd = fimg2d_get_first_command(info);
	if (!cmd) {
		printk(KERN_ERR "[%s] null command\n", __func__);
		goto next;
	}

	if (cmd->ctx->mm->pgd != phys_to_virt(pgtable_base)) {
		printk(KERN_ERR "[%s] pgtable base is different from current command\n",
				__func__);
		goto next;
	}

	fimg2d_dump_command(cmd);

next:
	fimg2d_clk_dump(info);
	info->dump(info);

	BUG();
	return 0;
}
Пример #2
0
struct fimg2d_bltcmd *fimg2d_get_command(struct fimg2d_control *ctrl)
{
	unsigned long flags;
	struct fimg2d_bltcmd *cmd;

	g2d_spin_lock(&ctrl->bltlock, flags);
	cmd = fimg2d_get_first_command(ctrl);
	g2d_spin_unlock(&ctrl->bltlock, flags);
	return cmd;
}
Пример #3
0
void fimg2d4x_bitblt(struct fimg2d_control *info)
{
	struct fimg2d_context *ctx;
	struct fimg2d_bltcmd *cmd;
	unsigned long *pgd;

	fimg2d_debug("enter blitter\n");

#ifdef CONFIG_PM_RUNTIME
	pm_runtime_get_sync(info->dev);
	fimg2d_debug("pm_runtime_get_sync\n");
#endif
	fimg2d_clk_on(info);

	while ((cmd = fimg2d_get_first_command(info))) {
		ctx = cmd->ctx;
		if (info->err) {
			printk(KERN_ERR "[%s] device error\n", __func__);
			goto blitend;
		}

		atomic_set(&info->busy, 1);

		info->configure(info, cmd);

		if (cmd->image[IDST].addr.type != ADDR_PHYS) {
			pgd = (unsigned long *)ctx->mm->pgd;
			s5p_sysmmu_enable(info->dev, (unsigned long)virt_to_phys(pgd));
			fimg2d_debug("sysmmu enable: pgd %p ctx %p seq_no(%u)\n",
					pgd, ctx, cmd->seq_no);
		}

		fimg2d4x_pre_bitblt(info, cmd);

#ifdef PERF_PROFILE
		perf_start(cmd->ctx, PERF_BLIT);
#endif
		/* start blit */
		info->run(info);
		fimg2d4x_blit_wait(info, cmd);

#ifdef PERF_PROFILE
		perf_end(cmd->ctx, PERF_BLIT);
#endif
		if (cmd->image[IDST].addr.type != ADDR_PHYS) {
			s5p_sysmmu_disable(info->dev);
			fimg2d_debug("sysmmu disable\n");
		}
blitend:
		spin_lock(&info->bltlock);
		fimg2d_dequeue(&cmd->node);
		kfree(cmd);
		atomic_dec(&ctx->ncmd);

		/* wake up context */
		if (!atomic_read(&ctx->ncmd))
			wake_up(&ctx->wait_q);
		spin_unlock(&info->bltlock);
	}

	atomic_set(&info->active, 0);

	fimg2d_clk_off(info);
#ifdef CONFIG_PM_RUNTIME
	pm_runtime_put_sync(info->dev);
	fimg2d_debug("pm_runtime_put_sync\n");
#endif

	fimg2d_debug("exit blitter\n");
}