mali_error kbase_prepare_soft_job(kbase_jd_atom *katom )
{
	switch(katom->core_req) {
		case BASE_JD_REQ_SOFT_DUMP_CPU_GPU_TIME:
			/* Nothing to do */
			break;
#ifdef CONFIG_SYNC
		case BASE_JD_REQ_SOFT_FENCE_TRIGGER:
			{
				base_fence fence;
				int fd;
				if (MALI_ERROR_NONE != ukk_copy_from_user(sizeof(fence), &fence, (__user void*)(uintptr_t)katom->jc))
				{
					return MALI_ERROR_FUNCTION_FAILED;
				}
				fd = kbase_stream_create_fence(fence.basep.stream_fd);
				if (fd < 0)
				{
					return MALI_ERROR_FUNCTION_FAILED;
				}
				katom->fence = sync_fence_fdget(fd);

				if (katom->fence == NULL)
				{
					/* The only way the fence can be NULL is if userspace closed it for us.
					 * So we don't need to clear it up */
					return MALI_ERROR_FUNCTION_FAILED;
				}
				fence.basep.fd = fd;
				if (MALI_ERROR_NONE != ukk_copy_to_user(sizeof(fence), (__user void*)(uintptr_t)katom->jc, &fence))
				{
					katom->fence = NULL;
					sys_close(fd);
					return MALI_ERROR_FUNCTION_FAILED;
				}
			}
			break;
		case BASE_JD_REQ_SOFT_FENCE_WAIT:
			{
				base_fence fence;
				if (MALI_ERROR_NONE != ukk_copy_from_user(sizeof(fence), &fence, (__user void*)(uintptr_t)katom->jc))
				{
					return MALI_ERROR_FUNCTION_FAILED;
				}

				/* Get a reference to the fence object */
				katom->fence = sync_fence_fdget(fence.basep.fd);
				if (katom->fence == NULL)
				{
					return MALI_ERROR_FUNCTION_FAILED;
				}
			}
			break;
#endif /* CONFIG_SYNC */
		default:
			/* Unsupported soft-job */
			return MALI_ERROR_FUNCTION_FAILED;
	}
	return MALI_ERROR_NONE;
}
Exemple #2
0
int sprd_fence_destroy(struct ion_fence_data *data)
{
	if (data == NULL)
	{
		printk(KERN_ERR "sprd_fence_destroy parameters NULL\n");
		return -EFAULT;
	}

	if (data->release_fence_fd >= 0)
	{
		struct sync_fence *fence = sync_fence_fdget(data->release_fence_fd);
		if (fence == NULL)
		{
			printk(KERN_ERR "sprd_fence_destroy failed fence == NULL\n");
			return -EFAULT;
		}
	}
	else if (data->retired_fence_fd >= 0)
	{
		struct sync_fence *fence = sync_fence_fdget(data->retired_fence_fd);
		if (fence == NULL)
		{
			printk(KERN_ERR "sprd_fence_destroy failed fence == NULL\n");
		}	return -EFAULT;
	}

	return 0;
}
Exemple #3
0
int sprd_fence_wait(int fence_fd)
{
	int ret = 0;

	struct sync_fence *fence = NULL;

	if (fence_fd < 0)
	{
		printk(KERN_ERR "sprd_wait_fence input parameters is NULL\n");
		return -EFAULT;
	}

	fence = sync_fence_fdget(fence_fd);
	if (fence == NULL)
	{
		printk(KERN_ERR "sprd_fence_wait failed fence == NULL\n");
		return -EFAULT;
	}

	ret = sync_fence_wait(fence, WAIT_FENCE_TIMEOUT);
	sync_fence_put(fence);
	if (ret < 0)
	{
		printk(KERN_ERR "sync_fence_wait failed, ret = %x\n", ret);
	}

	pr_debug("sprd_wait_fence wait fence: %p done\n", (void *)fence);

	return ret;
}
GED_ERROR ged_monitor_3D_fence_add(int fence_fd)
{
    int err;
    GED_MONITOR_3D_FENCE* psMonitor;

    psMonitor = (GED_MONITOR_3D_FENCE*)ged_alloc(sizeof(GED_MONITOR_3D_FENCE));
    if (!psMonitor)
    {
        return GED_ERROR_OOM;
    }

    sync_fence_waiter_init(&psMonitor->sSyncWaiter, ged_sync_cb);
    INIT_WORK(&psMonitor->sWork, ged_monitor_3D_fence_work_cb);
    psMonitor->psSyncFence = sync_fence_fdget(fence_fd);
    if (NULL == psMonitor->psSyncFence)
    {
        ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
        return GED_ERROR_INVALID_PARAMS;
    }

    err = sync_fence_wait_async(psMonitor->psSyncFence, &psMonitor->sSyncWaiter);

    if ((1 == err) || (0 > err))
    {
        sync_fence_put(psMonitor->psSyncFence);
        ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
    }
    else if (0 == err)
    {
        int iCount = atomic_add_return(1, &g_i32Count);
        if (iCount > 1)
        {
            if (0 == ged_monitor_3D_fence_disable)
            {
                //unsigned int uiFreqLevelID;
                //if (mtk_get_bottom_gpu_freq(&uiFreqLevelID))
                {
                    //if (uiFreqLevelID != 4)
                    {
#ifdef CONFIG_GPU_TRACEPOINTS
                        if (ged_monitor_3D_fence_systrace)
                        {
                            unsigned long long t = cpu_clock(smp_processor_id());
                            trace_gpu_sched_switch("Smart Boost", t, 1, 0, 1);
                        }
#endif
                        mtk_set_bottom_gpu_freq(4);
                    }
                }
            }
        }
    }

    if (ged_monitor_3D_fence_debug > 0)
    {
        GED_LOGI("[+]3D fences count = %d\n", atomic_read(&g_i32Count));
    }

    return GED_OK;
}
int fence_merge(char *const name, int fd1, int fd2)
{
    int fd = get_unused_fd();
    int err;
    struct sync_fence *fence1, *fence2, *fence3;

    if (fd < 0)
        return fd;

    fence1 = sync_fence_fdget(fd1);
    if (NULL == fence1) {
        err = -ENOENT;
        goto err_put_fd;
    }

    fence2 = sync_fence_fdget(fd2);
    if (NULL == fence2) {
        err = -ENOENT;
        goto err_put_fence1;
    }

    name[sizeof(name) - 1] = '\0';
    fence3 = sync_fence_merge(name, fence1, fence2);
    if (fence3 == NULL) {
        err = -ENOMEM;
        goto err_put_fence2;
    }

    sync_fence_install(fence3, fd);
    sync_fence_put(fence2);
    sync_fence_put(fence1);

    return fd;

err_put_fence2:
    sync_fence_put(fence2);

err_put_fence1:
    sync_fence_put(fence1);

err_put_fd:
    put_unused_fd(fd);
    return err;
}
int kbase_fence_validate(int fd)
{
	struct sync_fence *fence;

	fence = sync_fence_fdget(fd);
	if (!fence)
		return -EINVAL;

	sync_fence_put(fence);
	return 0;
}
GED_ERROR ged_monitor_3D_fence_add(int fence_fd)
{
    int err;
    GED_MONITOR_3D_FENCE* psMonitor = (GED_MONITOR_3D_FENCE*)ged_alloc(sizeof(GED_MONITOR_3D_FENCE));

#ifdef GED_DEBUG_MONITOR_3D_FENCE
    ged_log_buf_print(ghLogBuf_GED, "[+]ged_monitor_3D_fence_add");
#endif

    if (!psMonitor)
    {
        return GED_ERROR_OOM;
    }

    sync_fence_waiter_init(&psMonitor->sSyncWaiter, ged_sync_cb);
    INIT_WORK(&psMonitor->sWork, ged_monitor_3D_fence_work_cb);
    psMonitor->psSyncFence = sync_fence_fdget(fence_fd);
    if (NULL == psMonitor->psSyncFence)
    {
        ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
        return GED_ERROR_INVALID_PARAMS;
    }

#ifdef GED_DEBUG_MONITOR_3D_FENCE
    ged_log_buf_print(ghLogBuf_GED, "[+]sync_fence_wait_async");
#endif

    err = sync_fence_wait_async(psMonitor->psSyncFence, &psMonitor->sSyncWaiter);

#ifdef GED_DEBUG_MONITOR_3D_FENCE
    ged_log_buf_print(ghLogBuf_GED, "[-]sync_fence_wait_async, err = %d", err);
#endif

    if ((1 == err) || (0 > err))
    {
        sync_fence_put(psMonitor->psSyncFence);
        ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
    }
    else if (0 == err)
    {
        int iCount = atomic_add_return (1, &g_i32Count);
        if (iCount > 1)
        {
            //mtk_set_bottom_gpu_freq(iCount + 1);
            mtk_set_bottom_gpu_freq(4);
        }
    }

#ifdef GED_DEBUG_MONITOR_3D_FENCE
    ged_log_buf_print(ghLogBuf_GED, "[-]ged_monitor_3D_fence_add, count = %d", atomic_read(&g_i32Count));
#endif

    return GED_OK;
}
mali_error kbase_fence_validate(int fd)
{
	struct sync_fence *fence;

	fence = sync_fence_fdget(fd);
	if (NULL != fence) {
		sync_fence_put(fence);
		return MALI_ERROR_NONE;
	} else {
		return MALI_ERROR_FUNCTION_FAILED;
	}
}
Exemple #9
0
_mali_osk_errcode_t mali_fence_validate(int fd)
{
	struct sync_fence * fence;
	fence = sync_fence_fdget(fd);
	if (NULL != fence)
	{
		sync_fence_put(fence);
		return _MALI_OSK_ERR_OK;
	}
	else
	{
		return _MALI_OSK_ERR_FAULT;
	}
}
struct kgsl_sync_fence_waiter *kgsl_sync_fence_async_wait(int fd,
	void (*func)(void *priv), void *priv)
{
	struct kgsl_sync_fence_waiter *kwaiter;
	struct sync_fence *fence;
	int status;

	fence = sync_fence_fdget(fd);
	if (fence == NULL)
		return ERR_PTR(-EINVAL);

	/* create the waiter */
	kwaiter = kzalloc(sizeof(*kwaiter), GFP_ATOMIC);
	if (kwaiter == NULL) {
		sync_fence_put(fence);
		return ERR_PTR(-ENOMEM);
	}

	kwaiter->fence = fence;
	kwaiter->priv = priv;
	kwaiter->func = func;

	strlcpy(kwaiter->name, fence->name, sizeof(kwaiter->name));

	sync_fence_waiter_init((struct sync_fence_waiter *) kwaiter,
		kgsl_sync_callback);

	/* if status then error or signaled */
	status = sync_fence_wait_async(fence,
		(struct sync_fence_waiter *) kwaiter);
	if (status) {
		kfree(kwaiter);
		sync_fence_put(fence);
		if (status < 0)
			kwaiter = ERR_PTR(status);
		else
			kwaiter = NULL;
	}

	return kwaiter;
}
int k3fb_buf_sync_wait(int fence_fd)
{
	int ret = 0;
	struct sync_fence *fence = NULL;

	fence = sync_fence_fdget(fence_fd);
	if (fence == NULL){
		K3_FB_ERR("sync_fence_fdget failed!\n");
		return -EINVAL;
	}

	ret = sync_fence_wait(fence, BUF_SYNC_TIMEOUT_MSEC);
	if (ret == -ETIME)
		ret = sync_fence_wait(fence, BUF_SYNC_TIMEOUT_MSEC);

	if (ret < 0)
		K3_FB_WARNING("error waiting on fence: 0x%x\n", ret);

	sync_fence_put(fence);

	return ret;
}
s32 mali_timeline_sync_fence_create(struct mali_timeline_system *system, struct mali_timeline_fence *fence)
{
	u32 i;
	struct sync_fence *sync_fence_acc = NULL;

	MALI_DEBUG_ASSERT_POINTER(system);
	MALI_DEBUG_ASSERT_POINTER(fence);

	for (i = 0; i < MALI_TIMELINE_MAX; ++i) {
		struct mali_timeline *timeline;
		struct sync_fence *sync_fence;

		if (MALI_TIMELINE_NO_POINT == fence->points[i]) continue;

		timeline = system->timelines[i];
		MALI_DEBUG_ASSERT_POINTER(timeline);

		sync_fence = mali_timeline_sync_fence_create_and_add_tracker(timeline, fence->points[i]);
		if (NULL == sync_fence) goto error;

		if (NULL != sync_fence_acc) {
			/* Merge sync fences. */
			sync_fence_acc = mali_sync_fence_merge(sync_fence_acc, sync_fence);
			if (NULL == sync_fence_acc) goto error;
		} else {
			/* This was the first sync fence created. */
			sync_fence_acc = sync_fence;
		}
	}

	if (-1 != fence->sync_fd) {
		struct sync_fence *sync_fence;

		sync_fence = sync_fence_fdget(fence->sync_fd);
		if (NULL == sync_fence) goto error;

		if (NULL != sync_fence_acc) {
			sync_fence_acc = mali_sync_fence_merge(sync_fence_acc, sync_fence);
			if (NULL == sync_fence_acc) goto error;
		} else {
			sync_fence_acc = sync_fence;
		}
	}

	if (NULL == sync_fence_acc) {
		MALI_DEBUG_ASSERT_POINTER(system->signaled_sync_tl);

		/* There was nothing to wait on, so return an already signaled fence. */

		sync_fence_acc = mali_sync_timeline_create_signaled_fence(system->signaled_sync_tl);
		if (NULL == sync_fence_acc) goto error;
	}

	/* Return file descriptor for the accumulated sync fence. */
	return mali_sync_fence_fd_alloc(sync_fence_acc);

error:
	if (NULL != sync_fence_acc) {
		sync_fence_put(sync_fence_acc);
	}

	return -1;
}
Exemple #13
0
void *sde_sync_get(uint64_t fd)
{
	/* force signed compare, fdget accepts an int argument */
	return (signed int)fd >= 0 ? sync_fence_fdget(fd) : NULL;
}
/**
 * Check if fence has been signaled.
 *
 * @param system Timeline system.
 * @param fence Timeline fence.
 * @return MALI_TRUE if fence is signaled, MALI_FALSE if not.
 */
static mali_bool mali_timeline_fence_wait_check_status(struct mali_timeline_system *system, struct mali_timeline_fence *fence)
{
	int i;
	u32 tid = _mali_osk_get_tid();
	mali_bool ret = MALI_TRUE;
#if defined(CONFIG_SYNC)
	struct sync_fence *sync_fence = NULL;
#endif

	MALI_DEBUG_ASSERT_POINTER(system);
	MALI_DEBUG_ASSERT_POINTER(fence);

	mali_spinlock_reentrant_wait(system->spinlock, tid);

	for (i = 0; i < MALI_TIMELINE_MAX; ++i) {
		struct mali_timeline *timeline;
		mali_timeline_point   point;

		point = fence->points[i];

		if (likely(MALI_TIMELINE_NO_POINT == point)) {
			/* Fence contains no point on this timeline. */
			continue;
		}

		timeline = system->timelines[i];
		MALI_DEBUG_ASSERT_POINTER(timeline);

		if (unlikely(!mali_timeline_is_point_valid(timeline, point))) {
			MALI_PRINT_ERROR(("Mali Timeline: point %d is not valid (oldest=%d, next=%d)\n", point, timeline->point_oldest, timeline->point_next));
		}

		if (!mali_timeline_is_point_released(timeline, point)) {
			ret = MALI_FALSE;
			goto exit;
		}
	}

#if defined(CONFIG_SYNC)
	if (-1 != fence->sync_fd) {
		sync_fence = sync_fence_fdget(fence->sync_fd);
		if (likely(NULL != sync_fence)) {
#if LINUX_VERSION_CODE < KERNEL_VERSION(3, 17, 0)
			if (0 == sync_fence->status) {
#else
			if (0 == atomic_read(&sync_fence->status)) {
#endif
				ret = MALI_FALSE;
			}
		} else {
			MALI_PRINT_ERROR(("Mali Timeline: failed to get sync fence from fd %d\n", fence->sync_fd));
		}
	}
#endif /* defined(CONFIG_SYNC) */

exit:
	mali_spinlock_reentrant_signal(system->spinlock, tid);

#if defined(CONFIG_SYNC)
	if (NULL != sync_fence) {
		sync_fence_put(sync_fence);
	}
#endif /* defined(CONFIG_SYNC) */

	return ret;
}

mali_bool mali_timeline_fence_wait(struct mali_timeline_system *system, struct mali_timeline_fence *fence, u32 timeout)
{
	struct mali_timeline_fence_wait_tracker *wait;
	mali_timeline_point point;
	mali_bool ret;

	MALI_DEBUG_ASSERT_POINTER(system);
	MALI_DEBUG_ASSERT_POINTER(fence);

	MALI_DEBUG_PRINT(4, ("Mali Timeline: wait on fence\n"));

	if (MALI_TIMELINE_FENCE_WAIT_TIMEOUT_IMMEDIATELY == timeout) {
		return mali_timeline_fence_wait_check_status(system, fence);
	}

	wait = mali_timeline_fence_wait_tracker_alloc();
	if (unlikely(NULL == wait)) {
		MALI_PRINT_ERROR(("Mali Timeline: failed to allocate data for fence wait\n"));
		return MALI_FALSE;
	}

	wait->activated = MALI_FALSE;
	wait->system = system;

	/* Initialize refcount to two references.  The reference first will be released by this
	 * function after the wait is over.  The second reference will be released when the tracker
	 * is activated. */
	_mali_osk_atomic_init(&wait->refcount, 2);

	/* Add tracker to timeline system, but not to a timeline. */
	mali_timeline_tracker_init(&wait->tracker, MALI_TIMELINE_TRACKER_WAIT, fence, wait);
	point = mali_timeline_system_add_tracker(system, &wait->tracker, MALI_TIMELINE_NONE);
	MALI_DEBUG_ASSERT(MALI_TIMELINE_NO_POINT == point);
	MALI_IGNORE(point);

	/* Wait for the tracker to be activated or time out. */
	if (MALI_TIMELINE_FENCE_WAIT_TIMEOUT_NEVER == timeout) {
		_mali_osk_wait_queue_wait_event(system->wait_queue, mali_timeline_fence_wait_tracker_is_activated, (void *) wait);
	} else {
		_mali_osk_wait_queue_wait_event_timeout(system->wait_queue, mali_timeline_fence_wait_tracker_is_activated, (void *) wait, timeout);
	}

	ret = wait->activated;

	if (0 == _mali_osk_atomic_dec_return(&wait->refcount)) {
		mali_timeline_fence_wait_tracker_free(wait);
	}

	return ret;
}

void mali_timeline_fence_wait_activate(struct mali_timeline_fence_wait_tracker *wait)
{
	mali_scheduler_mask schedule_mask = MALI_SCHEDULER_MASK_EMPTY;

	MALI_DEBUG_ASSERT_POINTER(wait);
	MALI_DEBUG_ASSERT_POINTER(wait->system);

	MALI_DEBUG_PRINT(4, ("Mali Timeline: activation for fence wait tracker\n"));

	MALI_DEBUG_ASSERT(MALI_FALSE == wait->activated);
	wait->activated = MALI_TRUE;

	_mali_osk_wait_queue_wake_up(wait->system->wait_queue);

	/* Nothing can wait on this tracker, so nothing to schedule after release. */
	schedule_mask = mali_timeline_tracker_release(&wait->tracker);
	MALI_DEBUG_ASSERT(MALI_SCHEDULER_MASK_EMPTY == schedule_mask);
	MALI_IGNORE(schedule_mask);

	if (0 == _mali_osk_atomic_dec_return(&wait->refcount)) {
		mali_timeline_fence_wait_tracker_free(wait);
	}
}