// SPDX-License-Identifier: GPL-2.0-only /* * Copyright (C) 2013-2014 Red Hat * Author: Rob Clark <robdclark@gmail.com> * * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved.
*/
#include"adreno_gpu.h"
bool hang_debug = false;
MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!)");
module_param_named(hang_debug, hang_debug, bool, 0600);
bool snapshot_debugbus = false;
MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)");
module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600);
if (!gpu) {
dev_err_once(dev->dev, "no GPU device was found\n"); return NULL;
}
adreno_gpu = to_adreno_gpu(gpu);
/* * The number one reason for HW init to fail is if the firmware isn't * loaded yet. Try that first and don't bother continuing on * otherwise
*/
ret = adreno_load_fw(adreno_gpu); if (ret) return NULL;
if (gpu->funcs->ucode_load) {
ret = gpu->funcs->ucode_load(gpu); if (ret) return NULL;
}
/* * Now that we have firmware loaded, and are ready to begin * booting the gpu, go ahead and enable runpm:
*/
pm_runtime_enable(&pdev->dev);
ret = pm_runtime_get_sync(&pdev->dev); if (ret < 0) {
pm_runtime_put_noidle(&pdev->dev);
DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret); goto err_disable_rpm;
}
mutex_lock(&gpu->lock);
ret = msm_gpu_hw_init(gpu);
mutex_unlock(&gpu->lock); if (ret) {
DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret); goto err_put_rpm;
}
/* first search the compat strings for qcom,adreno-XYZ.W: */
ret = of_property_read_string_index(node, "compatible", 0, &compat); if (ret == 0) { unsignedint r, patch;
if (sscanf(compat, "qcom,adreno-%08x", chipid) == 1) return 0;
}
/* and if that fails, fall back to legacy "qcom,chipid" property: */
ret = of_property_read_u32(node, "qcom,chipid", chipid); if (ret) {
DRM_ERROR("%pOF: could not parse qcom,chipid: %d\n",
node, ret); return ret;
}
pr_warn("%pOF: Using legacy qcom,chipid binding!\n", node);
/* * We should be holding a runpm ref, which will prevent * runtime suspend. In the system suspend path, we've * already waited for active jobs to complete.
*/
WARN_ON_ONCE(gpu->active_submits);
return gpu->funcs->pm_suspend(gpu);
}
staticvoid suspend_scheduler(struct msm_gpu *gpu)
{ int i;
/* * Shut down the scheduler before we force suspend, so that * suspend isn't racing with scheduler kthread feeding us * more work. * * Note, we just want to park the thread, and let any jobs * that are already on the hw queue complete normally, as * opposed to the drm_sched_stop() path used for handling * faulting/timed-out jobs. We can't really cancel any jobs * already on the hw queue without racing with the GPU.
*/ for (i = 0; i < gpu->nr_rings; i++) { struct drm_gpu_scheduler *sched = &gpu->rb[i]->sched;
drm_sched_wqueue_stop(sched);
}
}
staticvoid resume_scheduler(struct msm_gpu *gpu)
{ int i;
for (i = 0; i < gpu->nr_rings; i++) { struct drm_gpu_scheduler *sched = &gpu->rb[i]->sched;
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.