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;
}
static void ged_monitor_3D_fence_work_cb(struct work_struct *psWork)
{
	GED_MONITOR_3D_FENCE *psMonitor;

    if (atomic_sub_return(1, &g_i32Count) < 1)
    {
        if (0 == ged_monitor_3D_fence_disable)
        {
            //unsigned int uiFreqLevelID;
            //if (mtk_get_bottom_gpu_freq(&uiFreqLevelID))
            {
                //if (uiFreqLevelID > 0)
                {
                    mtk_set_bottom_gpu_freq(0);
#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, 0, 0, 1);
                    }
#endif
                }
            }
        }
    }

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

	psMonitor = GED_CONTAINER_OF(psWork, GED_MONITOR_3D_FENCE, sWork);
    sync_fence_put(psMonitor->psSyncFence);
    ged_free(psMonitor, sizeof(GED_MONITOR_3D_FENCE));
}
void PVRGpuTraceWorkSwitch(
    IMG_UINT64 ui64HWTimestampInOSTime,
    const IMG_UINT32 ui32Pid,
    const IMG_UINT32 ui32ExtJobRef,
    const IMG_UINT32 ui32IntJobRef,
    const IMG_CHAR* pszWorkType,
    PVR_GPUTRACE_SWITCH_TYPE eSwType)
{
    PVRSRV_ERROR eError = PVRSRV_OK;
    PVRSRV_FTRACE_GPU_JOB* psJob = IMG_NULL;
    IMG_UINT32 ui32CtxId;

    PVR_ASSERT(pszWorkType);

    eError = GetCtxAndJobID(ui32Pid, ui32ExtJobRef, ui32IntJobRef,	&ui32CtxId,  &psJob);
    PVR_LOGRN_IF_ERROR(eError, "GetCtxAndJobID");

    PVR_ASSERT(psJob);

    /*
      Only trace switch event if the job's enqueue event was traced. Necessary
      for when the GPU tracing is disabled, apps run and re-enabled to avoid
      orphan switch events from appearing in the trace file.
    */
    if (PVRSRV_FTRACE_JOB_GET_FLAGS(psJob) & PVRSRV_FTRACE_JOB_FLAG_ENQUEUED)
    {
        if (eSwType == PVR_GPUTRACE_SWITCH_TYPE_END)
        {
            /* When the GPU goes idle, we need to trace a switch with a context
             * ID of 0.
             */
            ui32CtxId = 0;
        }

        trace_gpu_sched_switch(pszWorkType, ui64HWTimestampInOSTime,
                               ui32CtxId, KM_FTRACE_NO_PRIORITY, PVRSRV_FTRACE_JOB_GET_ID(psJob));
    }
}
Esempio n. 4
0
/* Group and scheduler must be locked when entering this function.  Both will be unlocked before
 * exiting. */
static void mali_gp_scheduler_schedule_internal_and_unlock(void)
{
    struct mali_gp_job *job = NULL;

    MALI_DEBUG_ASSERT_LOCK_HELD(slot.group->lock);
    MALI_DEBUG_ASSERT_LOCK_HELD(gp_scheduler_lock);

    if (0 < pause_count || MALI_GP_SLOT_STATE_IDLE != slot.state ||
            (_mali_osk_list_empty(&job_queue) && _mali_osk_list_empty(&job_queue_high))) {
        mali_gp_scheduler_unlock();
        mali_group_unlock(slot.group);
        MALI_DEBUG_PRINT(4, ("Mali GP scheduler: Nothing to schedule (paused=%u, idle slots=%u)\n",
                             pause_count, MALI_GP_SLOT_STATE_IDLE == slot.state ? 1 : 0));
#if defined(CONFIG_GPU_TRACEPOINTS) && defined(CONFIG_TRACEPOINTS)
        trace_gpu_sched_switch(mali_gp_get_hw_core_desc(group->gp_core), sched_clock(), 0, 0, 0);
#endif
        return; /* Nothing to do, so early out */
    }

    /* Get next job in queue */
    if (!_mali_osk_list_empty(&job_queue_high)) {
        job = _MALI_OSK_LIST_ENTRY(job_queue_high.next, struct mali_gp_job, list);
    } else {
void SystraceHWPerfPackets(PVRSRV_SGXDEV_INFO *psDevInfo, PVRSRV_SGX_HWPERF_CB_ENTRY* psSGXHWPerf, IMG_UINT32 ui32DataCount, IMG_UINT32 ui32SgxClockspeed)
{	
	IMG_UINT32 ui32PID, ui32FrameNo, ui32EvtType, ui32RTData, ui32Clocksx16Difference, ui32ClockMultiplier;
	
	IMG_UINT32 ui32SgxClocksx16 = 0;
	IMG_UINT32 i = 0;
	IMG_UINT64 ui64HostTimestamp = 0; 
	IMG_UINT64 ui64TimeDifference = 0;
	IMG_UINT64 ui64PacketTimeStamp = 0;
	
	IMG_UINT32 ui32JobID = 0;
	IMG_UINT32 ui32CtxID = 0;
	
	IMG_UINT64 ui64LastHostTimestamp = 0;
	IMG_UINT32 ui32LastSGXClocksx16 = 0;
		
	ui64LastHostTimestamp = psDevInfo->psSystraceData->ui64LastHostTimestamp;
	ui32LastSGXClocksx16 = psDevInfo->psSystraceData->ui32LastSGXClocksx16;
	ui64HostTimestamp = sched_clock();
	
	/*If this is the first packet read, use it as the initial reference*/
	if (ui64LastHostTimestamp == 0) 
	{
		if (ui32DataCount > 0)
		{
			ui64LastHostTimestamp = ui64HostTimestamp;
			ui32LastSGXClocksx16 = psSGXHWPerf[0].ui32Clocksx16;	
		}
	}
	
	/* SGX clockspeed reported 307200000 HZ */
	/* Get the ui32ClockMultipliertiplier per 1us*/
	ui32ClockMultiplier = (ui32SgxClockspeed)/(1000*1000);
	
	for(i = 0; i < ui32DataCount; ++i)
	{	
		ui32SgxClocksx16 = psSGXHWPerf[i].ui32Clocksx16;
		ui32EvtType = psSGXHWPerf[i].ui32Type;
		ui32FrameNo = psSGXHWPerf[i].ui32FrameNo;
		ui32PID = psSGXHWPerf[i].ui32PID;
		ui32RTData = psSGXHWPerf[i].ui32RTData;

		if ((ui32EvtType == PVRSRV_SGX_HWPERF_TYPE_TA_START) ||
			(ui32EvtType == PVRSRV_SGX_HWPERF_TYPE_TA_END) ||
			(ui32EvtType == PVRSRV_SGX_HWPERF_TYPE_3D_START) ||
			(ui32EvtType == PVRSRV_SGX_HWPERF_TYPE_3D_END))
		{
			/*Get the JobID*/
			GetCtxAndJobID(psDevInfo->psSystraceData, ui32PID, ui32FrameNo, ui32RTData, &ui32CtxID, &ui32JobID);
			
			/* Calculate the time difference in ns*/
			/* Get the clock difference */
			ui32Clocksx16Difference = (ui32SgxClocksx16 - ui32LastSGXClocksx16);
			/* Multipy it by 16 and 1000 to convert from us to ns */
			ui64TimeDifference = (16*ui32Clocksx16Difference*1000)/ui32ClockMultiplier;
			
			
			/* Add the time diff to the last time-stamp, in nanoseconds*/
			ui64PacketTimeStamp = (unsigned long long) ui64LastHostTimestamp + (unsigned long long)ui64TimeDifference;
			
			switch(ui32EvtType)
			{
				case PVRSRV_SGX_HWPERF_TYPE_TA_START:
					trace_gpu_sched_switch("TA", ui64PacketTimeStamp, ui32CtxID, ui32FrameNo, ui32JobID);
					break;
				
				case PVRSRV_SGX_HWPERF_TYPE_TA_END:
					trace_gpu_sched_switch("TA", ui64PacketTimeStamp, 0, ui32FrameNo, ui32JobID);
					break;
				
				case PVRSRV_SGX_HWPERF_TYPE_3D_START:
					trace_gpu_sched_switch("3D", ui64PacketTimeStamp, ui32CtxID, ui32FrameNo, ui32JobID);
					break;
				
				case PVRSRV_SGX_HWPERF_TYPE_3D_END:
					trace_gpu_sched_switch("3D", ui64PacketTimeStamp, 0, ui32FrameNo, ui32JobID);
					break;
				
				default:
				break;
			}	
		}
	}
	if(ui32DataCount > 0) 
	{
		psDevInfo->psSystraceData->ui32LastSGXClocksx16 = ui32SgxClocksx16;
	}
	/* Get the last set of packets timestamp and sleep 1ms */
	psDevInfo->psSystraceData->ui64LastHostTimestamp = ui64HostTimestamp;
}