1 // SPDX-License-Identifier: GPL-2.0-only 2 /* 3 * Copyright (C) 2013-2014 Red Hat 4 * Author: Rob Clark <robdclark@gmail.com> 5 * 6 * Copyright (c) 2014,2017 The Linux Foundation. All rights reserved. 7 */ 8 9 #include "adreno_gpu.h" 10 11 bool hang_debug = false; 12 MODULE_PARM_DESC(hang_debug, "Dump registers when hang is detected (can be slow!)"); 13 module_param_named(hang_debug, hang_debug, bool, 0600); 14 15 bool snapshot_debugbus = false; 16 MODULE_PARM_DESC(snapshot_debugbus, "Include debugbus sections in GPU devcoredump (if not fused off)"); 17 module_param_named(snapshot_debugbus, snapshot_debugbus, bool, 0600); 18 19 int enable_preemption = -1; 20 MODULE_PARM_DESC(enable_preemption, "Enable preemption (A7xx only) (1=on , 0=disable, -1=auto (default))"); 21 module_param(enable_preemption, int, 0600); 22 23 bool disable_acd; 24 MODULE_PARM_DESC(disable_acd, "Forcefully disable GPU ACD"); 25 module_param_unsafe(disable_acd, bool, 0400); 26 27 static bool skip_gpu; 28 MODULE_PARM_DESC(no_gpu, "Disable GPU driver register (0=enable GPU driver register (default), 1=skip GPU driver register"); 29 module_param(skip_gpu, bool, 0400); 30 31 extern const struct adreno_gpulist a2xx_gpulist; 32 extern const struct adreno_gpulist a3xx_gpulist; 33 extern const struct adreno_gpulist a4xx_gpulist; 34 extern const struct adreno_gpulist a5xx_gpulist; 35 extern const struct adreno_gpulist a6xx_gpulist; 36 extern const struct adreno_gpulist a7xx_gpulist; 37 38 static const struct adreno_gpulist *gpulists[] = { 39 &a2xx_gpulist, 40 &a3xx_gpulist, 41 &a4xx_gpulist, 42 &a5xx_gpulist, 43 &a6xx_gpulist, 44 &a7xx_gpulist, 45 }; 46 47 static const struct adreno_info *adreno_info(uint32_t chip_id) 48 { 49 /* identify gpu: */ 50 for (int i = 0; i < ARRAY_SIZE(gpulists); i++) { 51 for (int j = 0; j < gpulists[i]->gpus_count; j++) { 52 const struct adreno_info *info = &gpulists[i]->gpus[j]; 53 54 if (info->machine && !of_machine_is_compatible(info->machine)) 55 continue; 56 57 for (int k = 0; info->chip_ids[k]; k++) 58 if (info->chip_ids[k] == chip_id) 59 return info; 60 } 61 } 62 63 return NULL; 64 } 65 66 struct msm_gpu *adreno_load_gpu(struct drm_device *dev) 67 { 68 struct msm_drm_private *priv = dev->dev_private; 69 struct platform_device *pdev = priv->gpu_pdev; 70 struct msm_gpu *gpu = NULL; 71 struct adreno_gpu *adreno_gpu; 72 int ret; 73 74 if (pdev) 75 gpu = dev_to_gpu(&pdev->dev); 76 77 if (!gpu) { 78 dev_err_once(dev->dev, "no GPU device was found\n"); 79 return NULL; 80 } 81 82 adreno_gpu = to_adreno_gpu(gpu); 83 84 /* 85 * The number one reason for HW init to fail is if the firmware isn't 86 * loaded yet. Try that first and don't bother continuing on 87 * otherwise 88 */ 89 90 ret = adreno_load_fw(adreno_gpu); 91 if (ret) 92 return NULL; 93 94 if (gpu->funcs->ucode_load) { 95 ret = gpu->funcs->ucode_load(gpu); 96 if (ret) 97 return NULL; 98 } 99 100 /* 101 * Now that we have firmware loaded, and are ready to begin 102 * booting the gpu, go ahead and enable runpm: 103 */ 104 pm_runtime_enable(&pdev->dev); 105 106 ret = pm_runtime_get_sync(&pdev->dev); 107 if (ret < 0) { 108 pm_runtime_put_noidle(&pdev->dev); 109 DRM_DEV_ERROR(dev->dev, "Couldn't power up the GPU: %d\n", ret); 110 goto err_disable_rpm; 111 } 112 113 mutex_lock(&gpu->lock); 114 ret = msm_gpu_hw_init(gpu); 115 mutex_unlock(&gpu->lock); 116 if (ret) { 117 DRM_DEV_ERROR(dev->dev, "gpu hw init failed: %d\n", ret); 118 goto err_put_rpm; 119 } 120 121 pm_runtime_put_autosuspend(&pdev->dev); 122 123 #ifdef CONFIG_DEBUG_FS 124 if (gpu->funcs->debugfs_init) { 125 gpu->funcs->debugfs_init(gpu, dev->primary); 126 gpu->funcs->debugfs_init(gpu, dev->render); 127 } 128 #endif 129 130 return gpu; 131 132 err_put_rpm: 133 pm_runtime_put_sync_suspend(&pdev->dev); 134 err_disable_rpm: 135 pm_runtime_disable(&pdev->dev); 136 137 return NULL; 138 } 139 140 static int find_chipid(struct device_node *node, uint32_t *chipid) 141 { 142 const char *compat; 143 int ret; 144 145 /* first search the compat strings for qcom,adreno-XYZ.W: */ 146 ret = of_property_read_string_index(node, "compatible", 0, &compat); 147 if (ret == 0) { 148 unsigned int r, patch; 149 150 if (sscanf(compat, "qcom,adreno-%u.%u", &r, &patch) == 2 || 151 sscanf(compat, "amd,imageon-%u.%u", &r, &patch) == 2) { 152 uint32_t core, major, minor; 153 154 core = r / 100; 155 r %= 100; 156 major = r / 10; 157 r %= 10; 158 minor = r; 159 160 *chipid = (core << 24) | 161 (major << 16) | 162 (minor << 8) | 163 patch; 164 165 return 0; 166 } 167 168 if (sscanf(compat, "qcom,adreno-%08x", chipid) == 1) 169 return 0; 170 } 171 172 /* and if that fails, fall back to legacy "qcom,chipid" property: */ 173 ret = of_property_read_u32(node, "qcom,chipid", chipid); 174 if (ret) { 175 DRM_ERROR("%pOF: could not parse qcom,chipid: %d\n", 176 node, ret); 177 return ret; 178 } 179 180 pr_warn("%pOF: Using legacy qcom,chipid binding!\n", node); 181 182 return 0; 183 } 184 185 bool adreno_has_gpu(struct device_node *node) 186 { 187 const struct adreno_info *info; 188 uint32_t chip_id; 189 int ret; 190 191 if (skip_gpu) 192 return false; 193 194 ret = find_chipid(node, &chip_id); 195 if (ret) 196 return false; 197 198 info = adreno_info(chip_id); 199 if (!info) { 200 pr_warn("%pOF: Unknown GPU revision: %"ADRENO_CHIPID_FMT"\n", 201 node, ADRENO_CHIPID_ARGS(chip_id)); 202 return false; 203 } 204 205 return true; 206 } 207 208 static int adreno_bind(struct device *dev, struct device *master, void *data) 209 { 210 static struct adreno_platform_config config = {}; 211 const struct adreno_info *info; 212 struct msm_drm_private *priv = dev_get_drvdata(master); 213 struct drm_device *drm = priv->dev; 214 struct msm_gpu *gpu; 215 int ret; 216 217 ret = find_chipid(dev->of_node, &config.chip_id); 218 /* We shouldn't have gotten this far if we can't parse the chip_id */ 219 if (WARN_ON(ret)) 220 return ret; 221 222 dev->platform_data = &config; 223 priv->gpu_pdev = to_platform_device(dev); 224 225 info = adreno_info(config.chip_id); 226 /* We shouldn't have gotten this far if we don't recognize the GPU: */ 227 if (WARN_ON(!info)) 228 return -ENXIO; 229 230 config.info = info; 231 232 DBG("Found GPU: %"ADRENO_CHIPID_FMT, ADRENO_CHIPID_ARGS(config.chip_id)); 233 234 priv->is_a2xx = info->family < ADRENO_3XX; 235 priv->has_cached_coherent = 236 !!(info->quirks & ADRENO_QUIRK_HAS_CACHED_COHERENT); 237 238 gpu = info->init(drm); 239 if (IS_ERR(gpu)) { 240 dev_warn(drm->dev, "failed to load adreno gpu\n"); 241 return PTR_ERR(gpu); 242 } 243 244 ret = dev_pm_opp_of_find_icc_paths(dev, NULL); 245 if (ret) 246 return ret; 247 248 return 0; 249 } 250 251 static int adreno_system_suspend(struct device *dev); 252 static void adreno_unbind(struct device *dev, struct device *master, 253 void *data) 254 { 255 struct msm_drm_private *priv = dev_get_drvdata(master); 256 struct msm_gpu *gpu = dev_to_gpu(dev); 257 258 if (pm_runtime_enabled(dev)) 259 WARN_ON_ONCE(adreno_system_suspend(dev)); 260 gpu->funcs->destroy(gpu); 261 262 priv->gpu_pdev = NULL; 263 } 264 265 static const struct component_ops a3xx_ops = { 266 .bind = adreno_bind, 267 .unbind = adreno_unbind, 268 }; 269 270 static int adreno_probe(struct platform_device *pdev) 271 { 272 if (of_device_is_compatible(pdev->dev.of_node, "amd,imageon") || 273 msm_gpu_no_components()) 274 return msm_gpu_probe(pdev, &a3xx_ops); 275 276 return component_add(&pdev->dev, &a3xx_ops); 277 } 278 279 static void adreno_remove(struct platform_device *pdev) 280 { 281 struct msm_drm_private *priv = platform_get_drvdata(pdev); 282 283 if (priv->kms_init) 284 component_del(&pdev->dev, &a3xx_ops); 285 else 286 msm_gpu_remove(pdev, &a3xx_ops); 287 } 288 289 static void adreno_shutdown(struct platform_device *pdev) 290 { 291 WARN_ON_ONCE(adreno_system_suspend(&pdev->dev)); 292 } 293 294 static const struct of_device_id dt_match[] = { 295 { .compatible = "qcom,adreno" }, 296 { .compatible = "qcom,adreno-3xx" }, 297 /* for compatibility with imx5 gpu: */ 298 { .compatible = "amd,imageon" }, 299 /* for backwards compat w/ downstream kgsl DT files: */ 300 { .compatible = "qcom,kgsl-3d0" }, 301 {} 302 }; 303 304 static int adreno_runtime_resume(struct device *dev) 305 { 306 struct msm_gpu *gpu = dev_to_gpu(dev); 307 308 return gpu->funcs->pm_resume(gpu); 309 } 310 311 static int adreno_runtime_suspend(struct device *dev) 312 { 313 struct msm_gpu *gpu = dev_to_gpu(dev); 314 315 /* 316 * We should be holding a runpm ref, which will prevent 317 * runtime suspend. In the system suspend path, we've 318 * already waited for active jobs to complete. 319 */ 320 WARN_ON_ONCE(gpu->active_submits); 321 322 return gpu->funcs->pm_suspend(gpu); 323 } 324 325 static void suspend_scheduler(struct msm_gpu *gpu) 326 { 327 int i; 328 329 /* 330 * Shut down the scheduler before we force suspend, so that 331 * suspend isn't racing with scheduler kthread feeding us 332 * more work. 333 * 334 * Note, we just want to park the thread, and let any jobs 335 * that are already on the hw queue complete normally, as 336 * opposed to the drm_sched_stop() path used for handling 337 * faulting/timed-out jobs. We can't really cancel any jobs 338 * already on the hw queue without racing with the GPU. 339 */ 340 for (i = 0; i < gpu->nr_rings; i++) { 341 struct drm_gpu_scheduler *sched = &gpu->rb[i]->sched; 342 343 drm_sched_wqueue_stop(sched); 344 } 345 } 346 347 static void resume_scheduler(struct msm_gpu *gpu) 348 { 349 int i; 350 351 for (i = 0; i < gpu->nr_rings; i++) { 352 struct drm_gpu_scheduler *sched = &gpu->rb[i]->sched; 353 354 drm_sched_wqueue_start(sched); 355 } 356 } 357 358 static int adreno_system_suspend(struct device *dev) 359 { 360 struct msm_gpu *gpu = dev_to_gpu(dev); 361 int remaining, ret; 362 363 if (!gpu) 364 return 0; 365 366 suspend_scheduler(gpu); 367 368 remaining = wait_event_timeout(gpu->retire_event, 369 gpu->active_submits == 0, 370 msecs_to_jiffies(1000)); 371 if (remaining == 0) { 372 dev_err(dev, "Timeout waiting for GPU to suspend\n"); 373 ret = -EBUSY; 374 goto out; 375 } 376 377 ret = pm_runtime_force_suspend(dev); 378 out: 379 if (ret) 380 resume_scheduler(gpu); 381 382 return ret; 383 } 384 385 static int adreno_system_resume(struct device *dev) 386 { 387 struct msm_gpu *gpu = dev_to_gpu(dev); 388 389 if (!gpu) 390 return 0; 391 392 resume_scheduler(gpu); 393 return pm_runtime_force_resume(dev); 394 } 395 396 static const struct dev_pm_ops adreno_pm_ops = { 397 SYSTEM_SLEEP_PM_OPS(adreno_system_suspend, adreno_system_resume) 398 RUNTIME_PM_OPS(adreno_runtime_suspend, adreno_runtime_resume, NULL) 399 }; 400 401 static struct platform_driver adreno_driver = { 402 .probe = adreno_probe, 403 .remove = adreno_remove, 404 .shutdown = adreno_shutdown, 405 .driver = { 406 .name = "adreno", 407 .of_match_table = dt_match, 408 .pm = &adreno_pm_ops, 409 }, 410 }; 411 412 void __init adreno_register(void) 413 { 414 if (skip_gpu) 415 return; 416 417 platform_driver_register(&adreno_driver); 418 } 419 420 void __exit adreno_unregister(void) 421 { 422 if (skip_gpu) 423 return; 424 425 platform_driver_unregister(&adreno_driver); 426 } 427