예제 #1
0
void mali_gp_abort_job(struct mali_gp_core *core)
{
    MALI_DEBUG_ASSERT_POINTER(core);
    MALI_ASSERT_GROUP_LOCKED(core->group);

    if (_MALI_OSK_ERR_FAULT != mali_gp_reset(core))
    {
        _mali_osk_timer_del(core->timeout_timer);
    }
}
예제 #2
0
struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t *resource, struct mali_group *group)
{
	struct mali_gp_core *core = NULL;

	MALI_DEBUG_ASSERT(NULL == mali_global_gp_core);
	MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description));

	core = _mali_osk_malloc(sizeof(struct mali_gp_core));
	if (NULL != core) {
		if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE)) {
			_mali_osk_errcode_t ret;

			ret = mali_gp_reset(core);

			if (_MALI_OSK_ERR_OK == ret) {
				ret = mali_group_add_gp_core(group, core);
				if (_MALI_OSK_ERR_OK == ret) {
					/* Setup IRQ handlers (which will do IRQ probing if needed) */
					core->irq = _mali_osk_irq_init(resource->irq,
								       mali_group_upper_half_gp,
								       group,
								       mali_gp_irq_probe_trigger,
								       mali_gp_irq_probe_ack,
								       core,
								       resource->description);
					if (NULL != core->irq) {
						MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core));
						mali_global_gp_core = core;

						return core;
					} else {
						MALI_PRINT_ERROR(("Mali GP: Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description));
					}
					mali_group_remove_gp_core(group);
				} else {
					MALI_PRINT_ERROR(("Mali GP: Failed to add core %s to group\n", core->hw_core.description));
				}
			}
			mali_hw_core_delete(&core->hw_core);
		}

		_mali_osk_free(core);
	} else {
		MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n"));
	}

	return NULL;
}
/* Called from mali_cluster_reset() when the system is re-turned on */
void mali_group_reset(struct mali_group *group)
{
	mali_group_lock(group);

	group->session = NULL;

	if (NULL != group->mmu)
	{
		mali_mmu_reset(group->mmu);
	}

	if (NULL != group->gp_core)
	{
		mali_gp_reset(group->gp_core);
	}

	if (NULL != group->pp_core)
	{
		mali_pp_reset(group->pp_core);
	}

	mali_group_unlock(group);
}
예제 #4
0
struct mali_gp_core *mali_gp_create(const _mali_osk_resource_t * resource, struct mali_group *group)
{
    struct mali_gp_core* core = NULL;

    MALI_DEBUG_ASSERT(NULL == mali_global_gp_core);
    MALI_DEBUG_PRINT(2, ("Mali GP: Creating Mali GP core: %s\n", resource->description));

    core = _mali_osk_malloc(sizeof(struct mali_gp_core));
    if (NULL != core)
    {
        core->group = group;
        core->running_job = NULL;
        core->counter_src0 = MALI_HW_CORE_NO_COUNTER;
        core->counter_src1 = MALI_HW_CORE_NO_COUNTER;
        core->counter_src0_used = MALI_HW_CORE_NO_COUNTER;
        core->counter_src1_used = MALI_HW_CORE_NO_COUNTER;
        if (_MALI_OSK_ERR_OK == mali_hw_core_create(&core->hw_core, resource, MALIGP2_REGISTER_ADDRESS_SPACE_SIZE))
        {
            _mali_osk_errcode_t ret;

            mali_group_lock(group);
            ret = mali_gp_reset(core);
            mali_group_unlock(group);

            if (_MALI_OSK_ERR_OK == ret)
            {

                core->irq = _mali_osk_irq_init(resource->irq,
                                               mali_gp_upper_half,
                                               mali_gp_bottom_half,
                                               mali_gp_irq_probe_trigger,
                                               mali_gp_irq_probe_ack,
                                               core,
                                               "mali_gp_irq_handlers");
                if (NULL != core->irq)
                {

                    core->timeout_timer = _mali_osk_timer_init();
                    if(NULL != core->timeout_timer)
                    {
                        _mali_osk_timer_setcallback(core->timeout_timer, mali_gp_timeout, (void *)core);
                        MALI_DEBUG_PRINT(4, ("Mali GP: set global gp core from 0x%08X to 0x%08X\n", mali_global_gp_core, core));
                        mali_global_gp_core = core;

                        return core;
                    }
                    else
                    {
                        MALI_PRINT_ERROR(("Failed to setup timeout timer for GP core %s\n", core->hw_core.description));

                        _mali_osk_irq_term(core->irq);
                    }
                }
                else
                {
                    MALI_PRINT_ERROR(("Failed to setup interrupt handlers for GP core %s\n", core->hw_core.description));
                }
            }
            mali_hw_core_delete(&core->hw_core);
        }

        _mali_osk_free(core);
    }
    else
    {
        MALI_PRINT_ERROR(("Failed to allocate memory for GP core\n"));
    }

    return NULL;
}
/* Group lock need to be taken before calling mali_group_complete_jobs. Will release the lock here. */
static void mali_group_complete_jobs(struct mali_group *group, mali_bool complete_gp, mali_bool complete_pp, bool success)
{
	mali_bool need_group_reset = MALI_FALSE;
	mali_bool gp_success = success;
	mali_bool pp_success = success;

	MALI_ASSERT_GROUP_LOCKED(group);

	if (complete_gp && !complete_pp)
	{
		MALI_DEBUG_ASSERT_POINTER(group->gp_core);
		if (_MALI_OSK_ERR_OK == mali_gp_reset(group->gp_core))
		{
			struct mali_gp_job *gp_job_to_return = group->gp_running_job;
			group->gp_state = MALI_GROUP_CORE_STATE_IDLE;
			group->gp_running_job = NULL;

			MALI_DEBUG_ASSERT_POINTER(gp_job_to_return);

			mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return));

			if(mali_group_other_reschedule_needed(group))
			{
				mali_group_unlock(group);
				mali_pp_scheduler_do_schedule();
			}
			else
			{
				mali_group_unlock(group);
			}

			mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success);
			mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */

			return;
		}
		else
		{
			need_group_reset = MALI_TRUE;
			MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset GP, need to reset entire group\n"));
			pp_success = MALI_FALSE; /* This might kill PP as well, so this should fail */
		}
	}
	if (complete_pp && !complete_gp)
	{
		MALI_DEBUG_ASSERT_POINTER(group->pp_core);
		if (_MALI_OSK_ERR_OK == mali_pp_reset(group->pp_core))
		{
			struct mali_pp_job *pp_job_to_return = group->pp_running_job;
			u32 pp_sub_job_to_return = group->pp_running_sub_job;
			group->pp_state = MALI_GROUP_CORE_STATE_IDLE;
			group->pp_running_job = NULL;

			MALI_DEBUG_ASSERT_POINTER(pp_job_to_return);

			mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return));

			if(mali_group_other_reschedule_needed(group))
			{
				mali_group_unlock(group);
				mali_gp_scheduler_do_schedule();
			}
			else
			{
				mali_group_unlock(group);
			}

			mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success);
			mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */

			return;
		}
		else
		{
			need_group_reset = MALI_TRUE;
			MALI_DEBUG_PRINT(3, ("Mali group: Failed to reset PP, need to reset entire group\n"));
			gp_success = MALI_FALSE; /* This might kill GP as well, so this should fail */
		}
	}
	else if (complete_gp && complete_pp)
	{
		need_group_reset = MALI_TRUE;
	}

	if (MALI_TRUE == need_group_reset)
	{
		struct mali_gp_job *gp_job_to_return = group->gp_running_job;
		struct mali_pp_job *pp_job_to_return = group->pp_running_job;
		u32 pp_sub_job_to_return = group->pp_running_sub_job;
		mali_bool schedule_other = MALI_FALSE;

		MALI_DEBUG_PRINT(3, ("Mali group: Resetting entire group\n"));

		group->gp_state = MALI_GROUP_CORE_STATE_IDLE;
		group->gp_running_job = NULL;
		if (NULL != gp_job_to_return)
		{
			mali_group_deactivate_page_directory(group, mali_gp_job_get_session(gp_job_to_return));
		}

		group->pp_state = MALI_GROUP_CORE_STATE_IDLE;
		group->pp_running_job = NULL;
		if (NULL != pp_job_to_return)
		{
			mali_group_deactivate_page_directory(group, mali_pp_job_get_session(pp_job_to_return));
		}

		/* The reset has to be done after mali_group_deactivate_page_directory() */
		mali_group_recovery_reset(group);

		if (mali_group_other_reschedule_needed(group) && (NULL == gp_job_to_return || NULL == pp_job_to_return))
		{
			schedule_other = MALI_TRUE;
		}

		mali_group_unlock(group);

		if (NULL != gp_job_to_return)
		{
			mali_gp_scheduler_job_done(group, gp_job_to_return, gp_success);
			mali_pm_core_event(MALI_CORE_EVENT_GP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
		}
		else if (schedule_other)
		{
			mali_pp_scheduler_do_schedule();
		}

		if (NULL != pp_job_to_return)
		{
			mali_pp_scheduler_job_done(group, pp_job_to_return, pp_sub_job_to_return, pp_success);
			mali_pm_core_event(MALI_CORE_EVENT_PP_STOP); /* It is ok to do this after schedule, since START/STOP is simply ++ and -- anyways */
		}
		else if (schedule_other)
		{
			mali_gp_scheduler_do_schedule();
		}

		return;
	}

	mali_group_unlock(group);
}