Lines Matching +full:panfrost +full:- +full:gpu

1 // SPDX-License-Identifier: GPL-2.0
38 ret = pm_runtime_resume_and_get(pfdev->dev); in panfrost_ioctl_query_timestamp()
46 pm_runtime_put(pfdev->dev); in panfrost_ioctl_query_timestamp()
53 struct panfrost_device *pfdev = ddev->dev_private; in panfrost_ioctl_get_param()
56 if (param->pad != 0) in panfrost_ioctl_get_param()
57 return -EINVAL; in panfrost_ioctl_get_param()
61 param->value = pfdev->features.member; \ in panfrost_ioctl_get_param()
66 param->value = pfdev->features.member[param->param - \ in panfrost_ioctl_get_param()
70 switch (param->param) { in panfrost_ioctl_get_param()
98 ret = panfrost_ioctl_query_timestamp(pfdev, &param->value); in panfrost_ioctl_get_param()
105 param->value = arch_timer_get_cntfrq(); in panfrost_ioctl_get_param()
107 param->value = 0; in panfrost_ioctl_get_param()
112 return -EINVAL; in panfrost_ioctl_get_param()
121 struct panfrost_file_priv *priv = file->driver_priv; in panfrost_ioctl_create_bo()
127 if (!args->size || args->pad || in panfrost_ioctl_create_bo()
128 (args->flags & ~(PANFROST_BO_NOEXEC | PANFROST_BO_HEAP))) in panfrost_ioctl_create_bo()
129 return -EINVAL; in panfrost_ioctl_create_bo()
132 if ((args->flags & PANFROST_BO_HEAP) && in panfrost_ioctl_create_bo()
133 !(args->flags & PANFROST_BO_NOEXEC)) in panfrost_ioctl_create_bo()
134 return -EINVAL; in panfrost_ioctl_create_bo()
136 bo = panfrost_gem_create(dev, args->size, args->flags); in panfrost_ioctl_create_bo()
140 ret = drm_gem_handle_create(file, &bo->base.base, &args->handle); in panfrost_ioctl_create_bo()
146 args->offset = mapping->mmnode.start << PAGE_SHIFT; in panfrost_ioctl_create_bo()
153 ret = -EINVAL; in panfrost_ioctl_create_bo()
157 drm_gem_object_put(&bo->base.base); in panfrost_ioctl_create_bo()
162 * panfrost_lookup_bos() - Sets up job->bo[] with the GEM objects
180 struct panfrost_file_priv *priv = file_priv->driver_priv; in panfrost_lookup_bos()
185 job->bo_count = args->bo_handle_count; in panfrost_lookup_bos()
187 if (!job->bo_count) in panfrost_lookup_bos()
191 (void __user *)(uintptr_t)args->bo_handles, in panfrost_lookup_bos()
192 job->bo_count, &job->bos); in panfrost_lookup_bos()
196 job->mappings = kvmalloc_array(job->bo_count, in panfrost_lookup_bos()
199 if (!job->mappings) in panfrost_lookup_bos()
200 return -ENOMEM; in panfrost_lookup_bos()
202 for (i = 0; i < job->bo_count; i++) { in panfrost_lookup_bos()
205 bo = to_panfrost_bo(job->bos[i]); in panfrost_lookup_bos()
208 ret = -EINVAL; in panfrost_lookup_bos()
212 atomic_inc(&bo->gpu_usecount); in panfrost_lookup_bos()
213 job->mappings[i] = mapping; in panfrost_lookup_bos()
220 * panfrost_copy_in_sync() - Sets up job->deps with the sync objects
242 in_fence_count = args->in_sync_count; in panfrost_copy_in_sync()
249 ret = -ENOMEM; in panfrost_copy_in_sync()
255 (void __user *)(uintptr_t)args->in_syncs, in panfrost_copy_in_sync()
257 ret = -EFAULT; in panfrost_copy_in_sync()
263 ret = drm_sched_job_add_syncobj_dependency(&job->base, file_priv, in panfrost_copy_in_sync()
277 struct panfrost_device *pfdev = dev->dev_private; in panfrost_ioctl_submit()
278 struct panfrost_file_priv *file_priv = file->driver_priv; in panfrost_ioctl_submit()
284 if (!args->jc) in panfrost_ioctl_submit()
285 return -EINVAL; in panfrost_ioctl_submit()
287 if (args->requirements & ~JOB_REQUIREMENTS) in panfrost_ioctl_submit()
288 return -EINVAL; in panfrost_ioctl_submit()
290 if (args->out_sync > 0) { in panfrost_ioctl_submit()
291 sync_out = drm_syncobj_find(file, args->out_sync); in panfrost_ioctl_submit()
293 return -ENODEV; in panfrost_ioctl_submit()
298 ret = -ENOMEM; in panfrost_ioctl_submit()
302 kref_init(&job->refcount); in panfrost_ioctl_submit()
304 job->pfdev = pfdev; in panfrost_ioctl_submit()
305 job->jc = args->jc; in panfrost_ioctl_submit()
306 job->requirements = args->requirements; in panfrost_ioctl_submit()
307 job->flush_id = panfrost_gpu_get_latest_flush_id(pfdev); in panfrost_ioctl_submit()
308 job->mmu = file_priv->mmu; in panfrost_ioctl_submit()
309 job->engine_usage = &file_priv->engine_usage; in panfrost_ioctl_submit()
313 ret = drm_sched_job_init(&job->base, in panfrost_ioctl_submit()
314 &file_priv->sched_entity[slot], in panfrost_ioctl_submit()
333 drm_syncobj_replace_fence(sync_out, job->render_done_fence); in panfrost_ioctl_submit()
337 drm_sched_job_cleanup(&job->base); in panfrost_ioctl_submit()
354 unsigned long timeout = drm_timeout_abs_to_jiffies(args->timeout_ns); in panfrost_ioctl_wait_bo()
356 if (args->pad) in panfrost_ioctl_wait_bo()
357 return -EINVAL; in panfrost_ioctl_wait_bo()
359 gem_obj = drm_gem_object_lookup(file_priv, args->handle); in panfrost_ioctl_wait_bo()
361 return -ENOENT; in panfrost_ioctl_wait_bo()
363 ret = dma_resv_wait_timeout(gem_obj->resv, DMA_RESV_USAGE_READ, in panfrost_ioctl_wait_bo()
366 ret = timeout ? -ETIMEDOUT : -EBUSY; in panfrost_ioctl_wait_bo()
380 if (args->flags != 0) { in panfrost_ioctl_mmap_bo()
381 DRM_INFO("unknown mmap_bo flags: %d\n", args->flags); in panfrost_ioctl_mmap_bo()
382 return -EINVAL; in panfrost_ioctl_mmap_bo()
385 gem_obj = drm_gem_object_lookup(file_priv, args->handle); in panfrost_ioctl_mmap_bo()
387 DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); in panfrost_ioctl_mmap_bo()
388 return -ENOENT; in panfrost_ioctl_mmap_bo()
392 if (to_panfrost_bo(gem_obj)->is_heap) { in panfrost_ioctl_mmap_bo()
393 ret = -EINVAL; in panfrost_ioctl_mmap_bo()
399 args->offset = drm_vma_node_offset_addr(&gem_obj->vma_node); in panfrost_ioctl_mmap_bo()
409 struct panfrost_file_priv *priv = file_priv->driver_priv; in panfrost_ioctl_get_bo_offset()
415 gem_obj = drm_gem_object_lookup(file_priv, args->handle); in panfrost_ioctl_get_bo_offset()
417 DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); in panfrost_ioctl_get_bo_offset()
418 return -ENOENT; in panfrost_ioctl_get_bo_offset()
426 return -EINVAL; in panfrost_ioctl_get_bo_offset()
428 args->offset = mapping->mmnode.start << PAGE_SHIFT; in panfrost_ioctl_get_bo_offset()
436 struct panfrost_file_priv *priv = file_priv->driver_priv; in panfrost_ioctl_madvise()
438 struct panfrost_device *pfdev = dev->dev_private; in panfrost_ioctl_madvise()
443 gem_obj = drm_gem_object_lookup(file_priv, args->handle); in panfrost_ioctl_madvise()
445 DRM_DEBUG("Failed to look up GEM BO %d\n", args->handle); in panfrost_ioctl_madvise()
446 return -ENOENT; in panfrost_ioctl_madvise()
451 ret = dma_resv_lock_interruptible(bo->base.base.resv, NULL); in panfrost_ioctl_madvise()
455 mutex_lock(&pfdev->shrinker_lock); in panfrost_ioctl_madvise()
456 mutex_lock(&bo->mappings.lock); in panfrost_ioctl_madvise()
457 if (args->madv == PANFROST_MADV_DONTNEED) { in panfrost_ioctl_madvise()
460 first = list_first_entry(&bo->mappings.list, in panfrost_ioctl_madvise()
472 if (!list_is_singular(&bo->mappings.list) || in panfrost_ioctl_madvise()
473 WARN_ON_ONCE(first->mmu != priv->mmu)) { in panfrost_ioctl_madvise()
474 ret = -EINVAL; in panfrost_ioctl_madvise()
479 args->retained = drm_gem_shmem_madvise(&bo->base, args->madv); in panfrost_ioctl_madvise()
481 if (args->retained) { in panfrost_ioctl_madvise()
482 if (args->madv == PANFROST_MADV_DONTNEED) in panfrost_ioctl_madvise()
483 list_move_tail(&bo->base.madv_list, in panfrost_ioctl_madvise()
484 &pfdev->shrinker_list); in panfrost_ioctl_madvise()
485 else if (args->madv == PANFROST_MADV_WILLNEED) in panfrost_ioctl_madvise()
486 list_del_init(&bo->base.madv_list); in panfrost_ioctl_madvise()
490 mutex_unlock(&bo->mappings.lock); in panfrost_ioctl_madvise()
491 mutex_unlock(&pfdev->shrinker_lock); in panfrost_ioctl_madvise()
492 dma_resv_unlock(bo->base.base.resv); in panfrost_ioctl_madvise()
501 return -ENOSYS; in panfrost_unstable_ioctl_check()
510 struct panfrost_device *pfdev = dev->dev_private; in panfrost_open()
515 return -ENOMEM; in panfrost_open()
517 panfrost_priv->pfdev = pfdev; in panfrost_open()
518 file->driver_priv = panfrost_priv; in panfrost_open()
520 panfrost_priv->mmu = panfrost_mmu_ctx_create(pfdev); in panfrost_open()
521 if (IS_ERR(panfrost_priv->mmu)) { in panfrost_open()
522 ret = PTR_ERR(panfrost_priv->mmu); in panfrost_open()
533 panfrost_mmu_ctx_put(panfrost_priv->mmu); in panfrost_open()
542 struct panfrost_file_priv *panfrost_priv = file->driver_priv; in panfrost_postclose()
547 panfrost_mmu_ctx_put(panfrost_priv->mmu); in panfrost_postclose()
573 * IMPORTANT NOTE: drm-cycles and drm-engine measurements are not in panfrost_gpu_show_fdinfo()
575 * GPU cycles and CPU time spent in a given context. This is due to two in panfrost_gpu_show_fdinfo()
577 * - Firstly, we must consider the time the CPU and then the kernel in panfrost_gpu_show_fdinfo()
578 * takes to process the GPU interrupt, which means additional time and in panfrost_gpu_show_fdinfo()
579 * GPU cycles will be added in excess to the real figure. in panfrost_gpu_show_fdinfo()
580 * - Secondly, the pipelining done by the Job Manager (2 job slots per in panfrost_gpu_show_fdinfo()
582 * job spent on the GPU. in panfrost_gpu_show_fdinfo()
586 "fragment", "vertex-tiler", "compute-only" in panfrost_gpu_show_fdinfo()
591 for (i = 0; i < NUM_JOB_SLOTS - 1; i++) { in panfrost_gpu_show_fdinfo()
592 if (pfdev->profile_mode) { in panfrost_gpu_show_fdinfo()
593 drm_printf(p, "drm-engine-%s:\t%llu ns\n", in panfrost_gpu_show_fdinfo()
594 engine_names[i], panfrost_priv->engine_usage.elapsed_ns[i]); in panfrost_gpu_show_fdinfo()
595 drm_printf(p, "drm-cycles-%s:\t%llu\n", in panfrost_gpu_show_fdinfo()
596 engine_names[i], panfrost_priv->engine_usage.cycles[i]); in panfrost_gpu_show_fdinfo()
598 drm_printf(p, "drm-maxfreq-%s:\t%lu Hz\n", in panfrost_gpu_show_fdinfo()
599 engine_names[i], pfdev->pfdevfreq.fast_rate); in panfrost_gpu_show_fdinfo()
600 drm_printf(p, "drm-curfreq-%s:\t%lu Hz\n", in panfrost_gpu_show_fdinfo()
601 engine_names[i], pfdev->pfdevfreq.current_frequency); in panfrost_gpu_show_fdinfo()
607 struct drm_device *dev = file->minor->dev; in panfrost_show_fdinfo()
608 struct panfrost_device *pfdev = dev->dev_private; in panfrost_show_fdinfo()
610 panfrost_gpu_show_fdinfo(pfdev, file->driver_priv, p); in panfrost_show_fdinfo()
622 * Panfrost driver version:
623 * - 1.0 - initial interface
624 * - 1.1 - adds HEAP and NOEXEC flags for CREATE_BO
625 * - 1.2 - adds AFBC_FEATURES query
626 * - 1.3 - adds JD_REQ_CYCLE_COUNT job requirement for SUBMIT
627 * - adds SYSTEM_TIMESTAMP and SYSTEM_TIMESTAMP_FREQUENCY queries
637 .name = "panfrost",
638 .desc = "panfrost DRM",
652 pfdev = devm_kzalloc(&pdev->dev, sizeof(*pfdev), GFP_KERNEL); in panfrost_probe()
654 return -ENOMEM; in panfrost_probe()
656 pfdev->pdev = pdev; in panfrost_probe()
657 pfdev->dev = &pdev->dev; in panfrost_probe()
661 pfdev->comp = of_device_get_match_data(&pdev->dev); in panfrost_probe()
662 if (!pfdev->comp) in panfrost_probe()
663 return -ENODEV; in panfrost_probe()
665 pfdev->coherent = device_get_dma_attr(&pdev->dev) == DEV_DMA_COHERENT; in panfrost_probe()
668 ddev = drm_dev_alloc(&panfrost_drm_driver, &pdev->dev); in panfrost_probe()
672 ddev->dev_private = pfdev; in panfrost_probe()
673 pfdev->ddev = ddev; in panfrost_probe()
675 mutex_init(&pfdev->shrinker_lock); in panfrost_probe()
676 INIT_LIST_HEAD(&pfdev->shrinker_list); in panfrost_probe()
680 if (err != -EPROBE_DEFER) in panfrost_probe()
681 dev_err(&pdev->dev, "Fatal error during GPU init\n"); in panfrost_probe()
685 pm_runtime_set_active(pfdev->dev); in panfrost_probe()
686 pm_runtime_mark_last_busy(pfdev->dev); in panfrost_probe()
687 pm_runtime_enable(pfdev->dev); in panfrost_probe()
688 pm_runtime_set_autosuspend_delay(pfdev->dev, 50); /* ~3 frames */ in panfrost_probe()
689 pm_runtime_use_autosuspend(pfdev->dev); in panfrost_probe()
708 pm_runtime_disable(pfdev->dev); in panfrost_probe()
710 pm_runtime_set_suspended(pfdev->dev); in panfrost_probe()
719 struct drm_device *ddev = pfdev->ddev; in panfrost_remove()
724 pm_runtime_get_sync(pfdev->dev); in panfrost_remove()
725 pm_runtime_disable(pfdev->dev); in panfrost_remove()
727 pm_runtime_set_suspended(pfdev->dev); in panfrost_remove()
737 return sysfs_emit(buf, "%d\n", pfdev->profile_mode); in profiling_show()
752 pfdev->profile_mode = value; in profiling_store()
764 ATTRIBUTE_GROUPS(panfrost);
769 * and then initialize num_supplies with ARRAY_SIZE - 1.
773 .num_supplies = ARRAY_SIZE(default_supplies) - 1,
780 .num_supplies = ARRAY_SIZE(default_supplies) - 1,
787 * keep retro-compatibility with older devicetrees, as DVFS will
796 .num_supplies = ARRAY_SIZE(mediatek_mt8183_supplies) - 1,
804 .num_supplies = ARRAY_SIZE(mediatek_mt8183_b_supplies) - 1,
813 .num_supplies = ARRAY_SIZE(mediatek_mt8183_b_supplies) - 1,
822 .num_supplies = ARRAY_SIZE(mediatek_mt8183_b_supplies) - 1,
833 .num_supplies = ARRAY_SIZE(mediatek_mt8192_supplies) - 1,
842 { .compatible = "amlogic,meson-gxm-mali",
844 { .compatible = "amlogic,meson-g12a-mali",
846 { .compatible = "arm,mali-t604", .data = &default_data, },
847 { .compatible = "arm,mali-t624", .data = &default_data, },
848 { .compatible = "arm,mali-t628", .data = &default_data, },
849 { .compatible = "arm,mali-t720", .data = &default_data, },
850 { .compatible = "arm,mali-t760", .data = &default_data, },
851 { .compatible = "arm,mali-t820", .data = &default_data, },
852 { .compatible = "arm,mali-t830", .data = &default_data, },
853 { .compatible = "arm,mali-t860", .data = &default_data, },
854 { .compatible = "arm,mali-t880", .data = &default_data, },
855 { .compatible = "arm,mali-bifrost", .data = &default_data, },
856 { .compatible = "arm,mali-valhall-jm", .data = &default_data, },
857 { .compatible = "mediatek,mt8183-mali", .data = &mediatek_mt8183_data },
858 { .compatible = "mediatek,mt8183b-mali", .data = &mediatek_mt8183_b_data },
859 { .compatible = "mediatek,mt8186-mali", .data = &mediatek_mt8186_data },
860 { .compatible = "mediatek,mt8188-mali", .data = &mediatek_mt8188_data },
861 { .compatible = "mediatek,mt8192-mali", .data = &mediatek_mt8192_data },
870 .name = "panfrost",
878 MODULE_AUTHOR("Panfrost Project Developers");
879 MODULE_DESCRIPTION("Panfrost DRM Driver");