lima_drv.c 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489
  1. // SPDX-License-Identifier: GPL-2.0 OR MIT
  2. /* Copyright 2017-2019 Qiang Yu <yuq825@gmail.com> */
  3. #include <linux/module.h>
  4. #include <linux/of_platform.h>
  5. #include <linux/uaccess.h>
  6. #include <linux/slab.h>
  7. #include <linux/pm_runtime.h>
  8. #include <drm/drm_ioctl.h>
  9. #include <drm/drm_drv.h>
  10. #include <drm/drm_prime.h>
  11. #include <drm/lima_drm.h>
  12. #include "lima_device.h"
  13. #include "lima_drv.h"
  14. #include "lima_gem.h"
  15. #include "lima_vm.h"
  16. int lima_sched_timeout_ms;
  17. uint lima_heap_init_nr_pages = 8;
  18. uint lima_max_error_tasks;
  19. uint lima_job_hang_limit;
  20. MODULE_PARM_DESC(sched_timeout_ms, "task run timeout in ms");
  21. module_param_named(sched_timeout_ms, lima_sched_timeout_ms, int, 0444);
  22. MODULE_PARM_DESC(heap_init_nr_pages, "heap buffer init number of pages");
  23. module_param_named(heap_init_nr_pages, lima_heap_init_nr_pages, uint, 0444);
  24. MODULE_PARM_DESC(max_error_tasks, "max number of error tasks to save");
  25. module_param_named(max_error_tasks, lima_max_error_tasks, uint, 0644);
  26. MODULE_PARM_DESC(job_hang_limit, "number of times to allow a job to hang before dropping it (default 0)");
  27. module_param_named(job_hang_limit, lima_job_hang_limit, uint, 0444);
  28. static int lima_ioctl_get_param(struct drm_device *dev, void *data, struct drm_file *file)
  29. {
  30. struct drm_lima_get_param *args = data;
  31. struct lima_device *ldev = to_lima_dev(dev);
  32. if (args->pad)
  33. return -EINVAL;
  34. switch (args->param) {
  35. case DRM_LIMA_PARAM_GPU_ID:
  36. switch (ldev->id) {
  37. case lima_gpu_mali400:
  38. args->value = DRM_LIMA_PARAM_GPU_ID_MALI400;
  39. break;
  40. case lima_gpu_mali450:
  41. args->value = DRM_LIMA_PARAM_GPU_ID_MALI450;
  42. break;
  43. default:
  44. args->value = DRM_LIMA_PARAM_GPU_ID_UNKNOWN;
  45. break;
  46. }
  47. break;
  48. case DRM_LIMA_PARAM_NUM_PP:
  49. args->value = ldev->pipe[lima_pipe_pp].num_processor;
  50. break;
  51. case DRM_LIMA_PARAM_GP_VERSION:
  52. args->value = ldev->gp_version;
  53. break;
  54. case DRM_LIMA_PARAM_PP_VERSION:
  55. args->value = ldev->pp_version;
  56. break;
  57. default:
  58. return -EINVAL;
  59. }
  60. return 0;
  61. }
  62. static int lima_ioctl_gem_create(struct drm_device *dev, void *data, struct drm_file *file)
  63. {
  64. struct drm_lima_gem_create *args = data;
  65. if (args->pad)
  66. return -EINVAL;
  67. if (args->flags & ~(LIMA_BO_FLAG_HEAP))
  68. return -EINVAL;
  69. if (args->size == 0)
  70. return -EINVAL;
  71. return lima_gem_create_handle(dev, file, args->size, args->flags, &args->handle);
  72. }
  73. static int lima_ioctl_gem_info(struct drm_device *dev, void *data, struct drm_file *file)
  74. {
  75. struct drm_lima_gem_info *args = data;
  76. return lima_gem_get_info(file, args->handle, &args->va, &args->offset);
  77. }
  78. static int lima_ioctl_gem_submit(struct drm_device *dev, void *data, struct drm_file *file)
  79. {
  80. struct drm_lima_gem_submit *args = data;
  81. struct lima_device *ldev = to_lima_dev(dev);
  82. struct lima_drm_priv *priv = file->driver_priv;
  83. struct drm_lima_gem_submit_bo *bos;
  84. struct lima_sched_pipe *pipe;
  85. struct lima_sched_task *task;
  86. struct lima_ctx *ctx;
  87. struct lima_submit submit = {0};
  88. size_t size;
  89. int err = 0;
  90. if (args->pipe >= lima_pipe_num || args->nr_bos == 0)
  91. return -EINVAL;
  92. if (args->flags & ~(LIMA_SUBMIT_FLAG_EXPLICIT_FENCE))
  93. return -EINVAL;
  94. pipe = ldev->pipe + args->pipe;
  95. if (args->frame_size != pipe->frame_size)
  96. return -EINVAL;
  97. bos = kvcalloc(args->nr_bos, sizeof(*submit.bos) + sizeof(*submit.lbos), GFP_KERNEL);
  98. if (!bos)
  99. return -ENOMEM;
  100. size = args->nr_bos * sizeof(*submit.bos);
  101. if (copy_from_user(bos, u64_to_user_ptr(args->bos), size)) {
  102. err = -EFAULT;
  103. goto out0;
  104. }
  105. task = kmem_cache_zalloc(pipe->task_slab, GFP_KERNEL);
  106. if (!task) {
  107. err = -ENOMEM;
  108. goto out0;
  109. }
  110. task->frame = task + 1;
  111. if (copy_from_user(task->frame, u64_to_user_ptr(args->frame), args->frame_size)) {
  112. err = -EFAULT;
  113. goto out1;
  114. }
  115. err = pipe->task_validate(pipe, task);
  116. if (err)
  117. goto out1;
  118. ctx = lima_ctx_get(&priv->ctx_mgr, args->ctx);
  119. if (!ctx) {
  120. err = -ENOENT;
  121. goto out1;
  122. }
  123. submit.pipe = args->pipe;
  124. submit.bos = bos;
  125. submit.lbos = (void *)bos + size;
  126. submit.nr_bos = args->nr_bos;
  127. submit.task = task;
  128. submit.ctx = ctx;
  129. submit.flags = args->flags;
  130. submit.in_sync[0] = args->in_sync[0];
  131. submit.in_sync[1] = args->in_sync[1];
  132. submit.out_sync = args->out_sync;
  133. err = lima_gem_submit(file, &submit);
  134. lima_ctx_put(ctx);
  135. out1:
  136. if (err)
  137. kmem_cache_free(pipe->task_slab, task);
  138. out0:
  139. kvfree(bos);
  140. return err;
  141. }
  142. static int lima_ioctl_gem_wait(struct drm_device *dev, void *data, struct drm_file *file)
  143. {
  144. struct drm_lima_gem_wait *args = data;
  145. if (args->op & ~(LIMA_GEM_WAIT_READ|LIMA_GEM_WAIT_WRITE))
  146. return -EINVAL;
  147. return lima_gem_wait(file, args->handle, args->op, args->timeout_ns);
  148. }
  149. static int lima_ioctl_ctx_create(struct drm_device *dev, void *data, struct drm_file *file)
  150. {
  151. struct drm_lima_ctx_create *args = data;
  152. struct lima_drm_priv *priv = file->driver_priv;
  153. struct lima_device *ldev = to_lima_dev(dev);
  154. if (args->_pad)
  155. return -EINVAL;
  156. return lima_ctx_create(ldev, &priv->ctx_mgr, &args->id);
  157. }
  158. static int lima_ioctl_ctx_free(struct drm_device *dev, void *data, struct drm_file *file)
  159. {
  160. struct drm_lima_ctx_create *args = data;
  161. struct lima_drm_priv *priv = file->driver_priv;
  162. if (args->_pad)
  163. return -EINVAL;
  164. return lima_ctx_free(&priv->ctx_mgr, args->id);
  165. }
  166. static int lima_drm_driver_open(struct drm_device *dev, struct drm_file *file)
  167. {
  168. int err;
  169. struct lima_drm_priv *priv;
  170. struct lima_device *ldev = to_lima_dev(dev);
  171. priv = kzalloc(sizeof(*priv), GFP_KERNEL);
  172. if (!priv)
  173. return -ENOMEM;
  174. priv->vm = lima_vm_create(ldev);
  175. if (!priv->vm) {
  176. err = -ENOMEM;
  177. goto err_out0;
  178. }
  179. lima_ctx_mgr_init(&priv->ctx_mgr);
  180. file->driver_priv = priv;
  181. return 0;
  182. err_out0:
  183. kfree(priv);
  184. return err;
  185. }
  186. static void lima_drm_driver_postclose(struct drm_device *dev, struct drm_file *file)
  187. {
  188. struct lima_drm_priv *priv = file->driver_priv;
  189. lima_ctx_mgr_fini(&priv->ctx_mgr);
  190. lima_vm_put(priv->vm);
  191. kfree(priv);
  192. }
  193. static const struct drm_ioctl_desc lima_drm_driver_ioctls[] = {
  194. DRM_IOCTL_DEF_DRV(LIMA_GET_PARAM, lima_ioctl_get_param, DRM_RENDER_ALLOW),
  195. DRM_IOCTL_DEF_DRV(LIMA_GEM_CREATE, lima_ioctl_gem_create, DRM_RENDER_ALLOW),
  196. DRM_IOCTL_DEF_DRV(LIMA_GEM_INFO, lima_ioctl_gem_info, DRM_RENDER_ALLOW),
  197. DRM_IOCTL_DEF_DRV(LIMA_GEM_SUBMIT, lima_ioctl_gem_submit, DRM_RENDER_ALLOW),
  198. DRM_IOCTL_DEF_DRV(LIMA_GEM_WAIT, lima_ioctl_gem_wait, DRM_RENDER_ALLOW),
  199. DRM_IOCTL_DEF_DRV(LIMA_CTX_CREATE, lima_ioctl_ctx_create, DRM_RENDER_ALLOW),
  200. DRM_IOCTL_DEF_DRV(LIMA_CTX_FREE, lima_ioctl_ctx_free, DRM_RENDER_ALLOW),
  201. };
  202. DEFINE_DRM_GEM_FOPS(lima_drm_driver_fops);
  203. /**
  204. * Changelog:
  205. *
  206. * - 1.1.0 - add heap buffer support
  207. */
  208. static struct drm_driver lima_drm_driver = {
  209. .driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ,
  210. .open = lima_drm_driver_open,
  211. .postclose = lima_drm_driver_postclose,
  212. .ioctls = lima_drm_driver_ioctls,
  213. .num_ioctls = ARRAY_SIZE(lima_drm_driver_ioctls),
  214. .fops = &lima_drm_driver_fops,
  215. .name = "lima",
  216. .desc = "lima DRM",
  217. .date = "20191231",
  218. .major = 1,
  219. .minor = 1,
  220. .patchlevel = 0,
  221. .gem_create_object = lima_gem_create_object,
  222. .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
  223. .gem_prime_import_sg_table = drm_gem_shmem_prime_import_sg_table,
  224. .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
  225. .gem_prime_mmap = drm_gem_prime_mmap,
  226. };
  227. struct lima_block_reader {
  228. void *dst;
  229. size_t base;
  230. size_t count;
  231. size_t off;
  232. ssize_t read;
  233. };
  234. static bool lima_read_block(struct lima_block_reader *reader,
  235. void *src, size_t src_size)
  236. {
  237. size_t max_off = reader->base + src_size;
  238. if (reader->off < max_off) {
  239. size_t size = min_t(size_t, max_off - reader->off,
  240. reader->count);
  241. memcpy(reader->dst, src + (reader->off - reader->base), size);
  242. reader->dst += size;
  243. reader->off += size;
  244. reader->read += size;
  245. reader->count -= size;
  246. }
  247. reader->base = max_off;
  248. return !!reader->count;
  249. }
  250. static ssize_t lima_error_state_read(struct file *filp, struct kobject *kobj,
  251. struct bin_attribute *attr, char *buf,
  252. loff_t off, size_t count)
  253. {
  254. struct device *dev = kobj_to_dev(kobj);
  255. struct lima_device *ldev = dev_get_drvdata(dev);
  256. struct lima_sched_error_task *et;
  257. struct lima_block_reader reader = {
  258. .dst = buf,
  259. .count = count,
  260. .off = off,
  261. };
  262. mutex_lock(&ldev->error_task_list_lock);
  263. if (lima_read_block(&reader, &ldev->dump, sizeof(ldev->dump))) {
  264. list_for_each_entry(et, &ldev->error_task_list, list) {
  265. if (!lima_read_block(&reader, et->data, et->size))
  266. break;
  267. }
  268. }
  269. mutex_unlock(&ldev->error_task_list_lock);
  270. return reader.read;
  271. }
  272. static ssize_t lima_error_state_write(struct file *file, struct kobject *kobj,
  273. struct bin_attribute *attr, char *buf,
  274. loff_t off, size_t count)
  275. {
  276. struct device *dev = kobj_to_dev(kobj);
  277. struct lima_device *ldev = dev_get_drvdata(dev);
  278. struct lima_sched_error_task *et, *tmp;
  279. mutex_lock(&ldev->error_task_list_lock);
  280. list_for_each_entry_safe(et, tmp, &ldev->error_task_list, list) {
  281. list_del(&et->list);
  282. kvfree(et);
  283. }
  284. ldev->dump.size = 0;
  285. ldev->dump.num_tasks = 0;
  286. mutex_unlock(&ldev->error_task_list_lock);
  287. return count;
  288. }
  289. static const struct bin_attribute lima_error_state_attr = {
  290. .attr.name = "error",
  291. .attr.mode = 0600,
  292. .size = 0,
  293. .read = lima_error_state_read,
  294. .write = lima_error_state_write,
  295. };
  296. static int lima_pdev_probe(struct platform_device *pdev)
  297. {
  298. struct lima_device *ldev;
  299. struct drm_device *ddev;
  300. int err;
  301. err = lima_sched_slab_init();
  302. if (err)
  303. return err;
  304. ldev = devm_kzalloc(&pdev->dev, sizeof(*ldev), GFP_KERNEL);
  305. if (!ldev) {
  306. err = -ENOMEM;
  307. goto err_out0;
  308. }
  309. ldev->dev = &pdev->dev;
  310. ldev->id = (enum lima_gpu_id)of_device_get_match_data(&pdev->dev);
  311. platform_set_drvdata(pdev, ldev);
  312. /* Allocate and initialize the DRM device. */
  313. ddev = drm_dev_alloc(&lima_drm_driver, &pdev->dev);
  314. if (IS_ERR(ddev))
  315. return PTR_ERR(ddev);
  316. ddev->dev_private = ldev;
  317. ldev->ddev = ddev;
  318. err = lima_device_init(ldev);
  319. if (err)
  320. goto err_out1;
  321. err = lima_devfreq_init(ldev);
  322. if (err) {
  323. dev_err(&pdev->dev, "Fatal error during devfreq init\n");
  324. goto err_out2;
  325. }
  326. pm_runtime_set_active(ldev->dev);
  327. pm_runtime_mark_last_busy(ldev->dev);
  328. pm_runtime_set_autosuspend_delay(ldev->dev, 200);
  329. pm_runtime_use_autosuspend(ldev->dev);
  330. pm_runtime_enable(ldev->dev);
  331. /*
  332. * Register the DRM device with the core and the connectors with
  333. * sysfs.
  334. */
  335. err = drm_dev_register(ddev, 0);
  336. if (err < 0)
  337. goto err_out3;
  338. if (sysfs_create_bin_file(&ldev->dev->kobj, &lima_error_state_attr))
  339. dev_warn(ldev->dev, "fail to create error state sysfs\n");
  340. return 0;
  341. err_out3:
  342. pm_runtime_disable(ldev->dev);
  343. lima_devfreq_fini(ldev);
  344. err_out2:
  345. lima_device_fini(ldev);
  346. err_out1:
  347. drm_dev_put(ddev);
  348. err_out0:
  349. lima_sched_slab_fini();
  350. return err;
  351. }
  352. static int lima_pdev_remove(struct platform_device *pdev)
  353. {
  354. struct lima_device *ldev = platform_get_drvdata(pdev);
  355. struct drm_device *ddev = ldev->ddev;
  356. sysfs_remove_bin_file(&ldev->dev->kobj, &lima_error_state_attr);
  357. drm_dev_unregister(ddev);
  358. /* stop autosuspend to make sure device is in active state */
  359. pm_runtime_set_autosuspend_delay(ldev->dev, -1);
  360. pm_runtime_disable(ldev->dev);
  361. lima_devfreq_fini(ldev);
  362. lima_device_fini(ldev);
  363. drm_dev_put(ddev);
  364. lima_sched_slab_fini();
  365. return 0;
  366. }
  367. static const struct of_device_id dt_match[] = {
  368. { .compatible = "arm,mali-400", .data = (void *)lima_gpu_mali400 },
  369. { .compatible = "arm,mali-450", .data = (void *)lima_gpu_mali450 },
  370. {}
  371. };
  372. MODULE_DEVICE_TABLE(of, dt_match);
  373. static const struct dev_pm_ops lima_pm_ops = {
  374. SET_SYSTEM_SLEEP_PM_OPS(pm_runtime_force_suspend, pm_runtime_force_resume)
  375. SET_RUNTIME_PM_OPS(lima_device_suspend, lima_device_resume, NULL)
  376. };
  377. static struct platform_driver lima_platform_driver = {
  378. .probe = lima_pdev_probe,
  379. .remove = lima_pdev_remove,
  380. .driver = {
  381. .name = "lima",
  382. .pm = &lima_pm_ops,
  383. .of_match_table = dt_match,
  384. },
  385. };
  386. module_platform_driver(lima_platform_driver);
  387. MODULE_AUTHOR("Lima Project Developers");
  388. MODULE_DESCRIPTION("Lima DRM Driver");
  389. MODULE_LICENSE("GPL v2");