lima_drv.c 12 KB

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