/* Nice level for the higher priority GPU start thread */int adreno_wake_nice =-7;/**
* adreno_start() - Power up and initialize the GPU
* @device: Pointer to the KGSL device to power up
* @priority: Boolean flag to specify of the start should be scheduled in a low
* latency work queue
*
* Power up the GPU and initialize it. If priority is specified then elevate
* the thread priority for the duration of the start operation
*/intadreno_start(structkgsl_device*device,int priority){
structadreno_device*adreno_dev =ADRENO_DEVICE(device);// 当前进程nice值int nice =task_nice(current);int ret;// 如果指定以低延时的工作队列启动, 而且当前nice值低于-7, 则重新设置其nice值if(priority &&(adreno_wake_nice < nice))set_user_nice(current, adreno_wake_nice);// [见第1节]
ret =_adreno_start(adreno_dev);if(priority)set_user_nice(current, nice);return ret;}
1. _adreno_start
/**
* _adreno_start - Power up the GPU and prepare to accept commands
* @adreno_dev: Pointer to an adreno_device structure
*
* The core function that powers up and initalizes the GPU. This function is
* called at init and after coming out of SLUMBER
*/staticint_adreno_start(structadreno_device*adreno_dev){
structkgsl_device*device =KGSL_DEVICE(adreno_dev);conststructadreno_gpudev*gpudev =ADRENO_GPU_DEVICE(adreno_dev);int status;unsignedint state = device->state;
bool regulator_left_on;/* make sure ADRENO_DEVICE_STARTED is not set here */WARN_ON(test_bit(ADRENO_DEVICE_STARTED,&adreno_dev->priv));
regulator_left_on =regulators_left_on(device);/* Clear any GPU faults that might have been left over */adreno_clear_gpu_fault(adreno_dev);/* Put the GPU in a responsive state */// 改变GPU状态为KGSL_STATE_AWARE
status =kgsl_pwrctrl_change_state(device, KGSL_STATE_AWARE);if(status)goto error_pwr_off;/* Set any stale active contexts to NULL */adreno_set_active_ctxs_null(adreno_dev);/* Set the bit to indicate that we've just powered on */set_bit(ADRENO_DEVICE_PWRON,&adreno_dev->priv);/* Soft reset the GPU if a regulator is stuck on*/if(regulator_left_on)_soft_reset(adreno_dev);adreno_ringbuffer_set_global(adreno_dev,0);// 调用kgsl_iommu_ops中定义的kgsl_iommu_start启动IOMMU
status =kgsl_mmu_start(device);if(status)goto error_pwr_off;adreno_get_bus_counters(adreno_dev);adreno_clear_dcvs_counters(adreno_dev);/* Restore performance counter registers with saved values */adreno_perfcounter_restore(adreno_dev);/* Start the GPU */// 调用adreno_a6xx_gpudev中定义的a6xx_start启动GPU[第2节]
gpudev->start(adreno_dev);/* Re-initialize the coresight registers if applicable */adreno_coresight_start(adreno_dev);adreno_irqctrl(adreno_dev,1);// 启动性能计数器[见第3节]adreno_perfcounter_start(adreno_dev);/* Clear FSR here in case it is set from a previous pagefault */kgsl_mmu_clear_fsr(&device->mmu);// 调用adreno_a6xx_gpudev中定义的a6xx_rb_start启动adreno_ringbuffer[见第4节]
status = gpudev->rb_start(adreno_dev);if(status)goto error_pwr_off;/*
* At this point it is safe to assume that we recovered. Setting
* this field allows us to take a new snapshot for the next failure
* if we are prioritizing the first unrecoverable snapshot.
*/if(device->snapshot)
device->snapshot->recovered = true;/* Start the dispatcher */// 开启adreno_dispatcher的调度[见第5节]adreno_dispatcher_start(device);
device->reset_counter++;set_bit(ADRENO_DEVICE_STARTED,&adreno_dev->priv);return0;
error_pwr_off:/* set the state back to original state */kgsl_pwrctrl_change_state(device, state);return status;}