adreno_device.c 9.9 KB

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