Example #1
0
_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
{
	/* Bus must be stopped before calling this function */
	const int reset_finished_loop_count = 15;
	const u32 reset_invalid_value = 0xC0FFE000;
	const u32 reset_check_value = 0xC01A0000;
	int i;

	MALI_DEBUG_ASSERT_POINTER(core);
	MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description));
	MALI_ASSERT_GROUP_LOCKED(core->group);

	mali_pp_post_process_job(core); /* @@@@?is there some cases where it is unsafe to post process the job here? */

	/* Set register to a bogus value. The register will be used to detect when reset is complete */
	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value);

	/* Force core to reset */
	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET);

	/* Wait for reset to be complete */
	for (i = 0; i < reset_finished_loop_count; i++)
	{
		mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_check_value);
		if (reset_check_value == mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW))
		{
			break;
		}
		_mali_osk_time_ubusydelay(10);
	}

	if (i == reset_finished_loop_count)
	{
		MALI_PRINT_ERROR(("Mali PP: The hard reset loop didn't work, unable to recover\n"));
	}

	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, 0x00000000); /* set it back to the default */
	/* Re-enable interrupts */
	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);

	return _MALI_OSK_ERR_OK;
}
Example #2
0
_mali_osk_errcode_t mali_pp_hard_reset(struct mali_pp_core *core)
{

    const int reset_finished_loop_count = 15;
    const u32 reset_invalid_value = 0xC0FFE000;
    const u32 reset_check_value = 0xC01A0000;
    int i;

    MALI_DEBUG_ASSERT_POINTER(core);
    MALI_DEBUG_PRINT(2, ("Mali PP: Hard reset of core %s\n", core->hw_core.description));
    MALI_ASSERT_GROUP_LOCKED(core->group);

    mali_pp_post_process_job(core);


    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_invalid_value);


    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_FORCE_RESET);


    for (i = 0; i < reset_finished_loop_count; i++)
    {
        mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, reset_check_value);
        if (reset_check_value == mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW))
        {
            break;
        }
        _mali_osk_time_ubusydelay(10);
    }

    if (i == reset_finished_loop_count)
    {
        MALI_PRINT_ERROR(("Mali PP: The hard reset loop didn't work, unable to recover\n"));
    }

    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_WRITE_BOUNDARY_LOW, 0x00000000);

    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);

    return _MALI_OSK_ERR_OK;
}
Example #3
0
static void mali_pp_bottom_half(void *data)
{
	struct mali_pp_core *core = (struct mali_pp_core *)data;
	u32 irq_readout;
	u32 irq_errors;

#if MALI_TIMELINE_PROFILING_ENABLED
#if 0  /* Bottom half TLP logging is currently not supported */
	_mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE ,  _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
#endif
#endif

	mali_group_lock(core->group); /* Group lock grabbed in core handlers, but released in common group handler */

	if ( MALI_FALSE == mali_group_power_is_on(core->group) )
	{
		MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description));
		mali_group_unlock(core->group);
#if MALI_TIMELINE_PROFILING_ENABLED
#if 0
		_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
#endif
#endif
		return;
	}

	irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED;

	MALI_DEBUG_PRINT(4, ("Mali PP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description));

	if (irq_readout & MALI200_REG_VAL_IRQ_END_OF_FRAME)
	{
		mali_pp_post_process_job(core);
		MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler\n"));
		mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_COMPLETED); /* Will release group lock */
#if MALI_TIMELINE_PROFILING_ENABLED
#if 0
		_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
#endif
#endif
		return;
	}

	/*
	 * Now lets look at the possible error cases (IRQ indicating error or timeout)
	 * END_OF_FRAME and HANG interrupts are not considered error.
	 */
	irq_errors = irq_readout & ~(MALI200_REG_VAL_IRQ_END_OF_FRAME|MALI200_REG_VAL_IRQ_HANG);
	if (0 != irq_errors)
	{
		mali_pp_post_process_job(core);
		MALI_PRINT_ERROR(("Mali PP: Unknown interrupt 0x%08X from core %s, aborting job\n",
		                  irq_readout, core->hw_core.description));
		mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_FAILED); /* Will release group lock */
#if MALI_TIMELINE_PROFILING_ENABLED
#if 0
		_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
#endif
#endif
		return;
	}
	else if (MALI_TRUE == core->core_timed_out) /* SW timeout */
	{
		if (core->timeout_job_id == mali_pp_job_get_id(core->running_job))
		{
			mali_pp_post_process_job(core);
			MALI_DEBUG_PRINT(2, ("Mali PP: Job %d timed out on core %s\n",
			                 mali_pp_job_get_id(core->running_job), core->hw_core.description));
			mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_TIMED_OUT); /* Will release group lock */
		}
		else
		{
			mali_group_unlock(core->group);
		}
		core->core_timed_out = MALI_FALSE;
#if MALI_TIMELINE_PROFILING_ENABLED
#if 0
		_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
#endif
#endif
		return;
	}
	else if (irq_readout & MALI200_REG_VAL_IRQ_HANG)
	{
		/* Just ignore hang interrupts, the job timer will detect hanging jobs anyways */
		mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_HANG);
	}

	/*
	 * The only way to get here is if we got a HANG interrupt, which we ignore.
	 * Re-enable interrupts and let core continue to run
	 */
	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
	mali_group_unlock(core->group);

#if MALI_TIMELINE_PROFILING_ENABLED
#if 0   /* Bottom half TLP logging is currently not supported */
	_mali_osk_profiling_add_event(MALI_PROFILING_EVENT_TYPE_STOP|MALI_PROFILING_EVENT_CHANNEL_SOFTWARE|MALI_PROFILING_EVENT_REASON_START_STOP_BOTTOM_HALF, 0, _mali_osk_get_tid(), 0, 0, 0);
#endif
#endif
}
Example #4
0
_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core)
{
	int i;
	const int request_loop_count = 20;

	MALI_DEBUG_ASSERT_POINTER(core);
	MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description));
	MALI_ASSERT_GROUP_LOCKED(core->group);

	mali_pp_post_process_job(core); /* @@@@?is there some cases where it is unsafe to post process the job here? */

	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0); /* disable the IRQs */


#if defined(USING_MALI200)

	/* On Mali-200, stop the  bus, then do a hard reset of the core */

	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);

	for (i = 0; i < request_loop_count; i++)
	{
		if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
		{
			break;
		}
		_mali_osk_time_ubusydelay(10);
	}

	if (request_loop_count == i)
	{
		MALI_PRINT_ERROR(("Mali PP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description));
		return _MALI_OSK_ERR_FAULT ;
	}

	/* the bus was stopped OK, do the hard reset */
	mali_pp_hard_reset(core);

#elif defined(USING_MALI400)

	/* Mali-300 and Mali-400 have a safe reset command which we use */

	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI400PP_REG_VAL_IRQ_RESET_COMPLETED);
	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);

	for (i = 0; i < request_loop_count; i++)
	{
		if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED)
		{
			break;
		}
		_mali_osk_time_ubusydelay(10);
	}

	if (request_loop_count == i)
	{
		MALI_DEBUG_PRINT(2, ("Mali PP: Failed to reset core %s, Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
		return _MALI_OSK_ERR_FAULT;
	}
#else
#error "no supported mali core defined"
#endif

	/* Re-enable interrupts */
	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
	mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);

	return _MALI_OSK_ERR_OK;
}
Example #5
0
static void mali_pp_bottom_half(void *data)
{
    struct mali_pp_core *core = (struct mali_pp_core *)data;
    u32 irq_readout;
    u32 irq_errors;

#if MALI_TIMELINE_PROFILING_ENABLED
#if 0
    _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_START| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE ,  _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
#endif
#endif

    mali_group_lock(core->group);

    if ( MALI_FALSE == mali_group_power_is_on(core->group) )
    {
        MALI_PRINT_ERROR(("Interrupt bottom half of %s when core is OFF.", core->hw_core.description));
        mali_group_unlock(core->group);
        return;
    }

    irq_readout = mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI200_REG_VAL_IRQ_MASK_USED;

    MALI_DEBUG_PRINT(4, ("Mali PP: Bottom half IRQ 0x%08X from core %s\n", irq_readout, core->hw_core.description));

    if (irq_readout & MALI200_REG_VAL_IRQ_END_OF_FRAME)
    {
        mali_pp_post_process_job(core);
        MALI_DEBUG_PRINT(3, ("Mali PP: Job completed, calling group handler\n"));
        mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_COMPLETED);
        return;
    }

    irq_errors = irq_readout & ~(MALI200_REG_VAL_IRQ_END_OF_FRAME|MALI200_REG_VAL_IRQ_HANG);
    if (0 != irq_errors)
    {
        mali_pp_post_process_job(core);
        MALI_PRINT_ERROR(("Mali PP: Unknown interrupt 0x%08X from core %s, aborting job\n",
                          irq_readout, core->hw_core.description));
        mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_FAILED);
        return;
    }
    else if (MALI_TRUE == core->core_timed_out)
    {
        if (core->timeout_job_id == mali_pp_job_get_id(core->running_job))
        {
            mali_pp_post_process_job(core);
            MALI_DEBUG_PRINT(2, ("Mali PP: Job %d timed out on core %s\n",
                                 mali_pp_job_get_id(core->running_job), core->hw_core.description));
            mali_group_bottom_half(core->group, GROUP_EVENT_PP_JOB_TIMED_OUT);
        }
        else
        {
            mali_group_unlock(core->group);
        }
        core->core_timed_out = MALI_FALSE;
        return;
    }
    else if (irq_readout & MALI200_REG_VAL_IRQ_HANG)
    {

        mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_HANG);
    }

    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);
    mali_group_unlock(core->group);

#if MALI_TIMELINE_PROFILING_ENABLED
#if 0
    _mali_osk_profiling_add_event( MALI_PROFILING_EVENT_TYPE_STOP| MALI_PROFILING_EVENT_CHANNEL_SOFTWARE ,  _mali_osk_get_pid(), _mali_osk_get_tid(), 0, 0, 0);
#endif
#endif
}
Example #6
0
_mali_osk_errcode_t mali_pp_reset(struct mali_pp_core *core)
{
    int i;
    const int request_loop_count = 20;

    MALI_DEBUG_ASSERT_POINTER(core);
    MALI_DEBUG_PRINT(4, ("Mali PP: Reset of core %s\n", core->hw_core.description));
    MALI_ASSERT_GROUP_LOCKED(core->group);

    mali_pp_post_process_job(core);

    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, 0);

#if defined(USING_MALI200)



    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI200_REG_VAL_CTRL_MGMT_STOP_BUS);

    for (i = 0; i < request_loop_count; i++)
    {
        if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS) & MALI200_REG_VAL_STATUS_BUS_STOPPED)
        {
            break;
        }
        _mali_osk_time_ubusydelay(10);
    }

    if (request_loop_count == i)
    {
        MALI_PRINT_ERROR(("Mali PP: Failed to stop bus for core %s, unable to recover\n", core->hw_core.description));
        return _MALI_OSK_ERR_FAULT ;
    }


    mali_pp_hard_reset(core);

#elif defined(USING_MALI400)



    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI400PP_REG_VAL_IRQ_RESET_COMPLETED);
    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_CTRL_MGMT, MALI400PP_REG_VAL_CTRL_MGMT_SOFT_RESET);

    for (i = 0; i < request_loop_count; i++)
    {
        if (mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_RAWSTAT) & MALI400PP_REG_VAL_IRQ_RESET_COMPLETED)
        {
            break;
        }
        _mali_osk_time_ubusydelay(10);
    }

    if (request_loop_count == i)
    {
        MALI_DEBUG_PRINT(2, ("Mali PP: Failed to reset core %s, Status: 0x%08x\n", core->hw_core.description, mali_hw_core_register_read(&core->hw_core, MALI200_REG_ADDR_MGMT_STATUS)));
        return _MALI_OSK_ERR_FAULT;
    }
#else
#error "no supported mali core defined"
#endif


    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_CLEAR, MALI200_REG_VAL_IRQ_MASK_ALL);
    mali_hw_core_register_write(&core->hw_core, MALI200_REG_ADDR_MGMT_INT_MASK, MALI200_REG_VAL_IRQ_MASK_USED);

    return _MALI_OSK_ERR_OK;
}