summaryrefslogtreecommitdiff
path: root/drivers/gpu/drm/panfrost/panfrost_drv.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/gpu/drm/panfrost/panfrost_drv.c')
-rw-r--r--drivers/gpu/drm/panfrost/panfrost_drv.c109
1 files changed, 96 insertions, 13 deletions
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index a926d71e8131..0f3935556ac7 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -3,6 +3,10 @@
/* Copyright 2019 Linaro, Ltd., Rob Herring <robh@kernel.org> */
/* Copyright 2019 Collabora ltd. */
+#ifdef CONFIG_ARM_ARCH_TIMER
+#include <asm/arch_timer.h>
+#endif
+
#include <linux/module.h>
#include <linux/of.h>
#include <linux/pagemap.h>
@@ -20,15 +24,34 @@
#include "panfrost_job.h"
#include "panfrost_gpu.h"
#include "panfrost_perfcnt.h"
-#include "panfrost_debugfs.h"
+
+#define JOB_REQUIREMENTS (PANFROST_JD_REQ_FS | PANFROST_JD_REQ_CYCLE_COUNT)
static bool unstable_ioctls;
module_param_unsafe(unstable_ioctls, bool, 0600);
+static int panfrost_ioctl_query_timestamp(struct panfrost_device *pfdev,
+ u64 *arg)
+{
+ int ret;
+
+ ret = pm_runtime_resume_and_get(pfdev->dev);
+ if (ret)
+ return ret;
+
+ panfrost_cycle_counter_get(pfdev);
+ *arg = panfrost_timestamp_read(pfdev);
+ panfrost_cycle_counter_put(pfdev);
+
+ pm_runtime_put(pfdev->dev);
+ return 0;
+}
+
static int panfrost_ioctl_get_param(struct drm_device *ddev, void *data, struct drm_file *file)
{
struct drm_panfrost_get_param *param = data;
struct panfrost_device *pfdev = ddev->dev_private;
+ int ret;
if (param->pad != 0)
return -EINVAL;
@@ -70,6 +93,21 @@ static int panfrost_ioctl_get_param(struct drm_device *ddev, void *data, struct
PANFROST_FEATURE_ARRAY(JS_FEATURES, js_features, 15);
PANFROST_FEATURE(NR_CORE_GROUPS, nr_core_groups);
PANFROST_FEATURE(THREAD_TLS_ALLOC, thread_tls_alloc);
+
+ case DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP:
+ ret = panfrost_ioctl_query_timestamp(pfdev, &param->value);
+ if (ret)
+ return ret;
+ break;
+
+ case DRM_PANFROST_PARAM_SYSTEM_TIMESTAMP_FREQUENCY:
+#ifdef CONFIG_ARM_ARCH_TIMER
+ param->value = arch_timer_get_cntfrq();
+#else
+ param->value = 0;
+#endif
+ break;
+
default:
return -EINVAL;
}
@@ -246,7 +284,7 @@ static int panfrost_ioctl_submit(struct drm_device *dev, void *data,
if (!args->jc)
return -EINVAL;
- if (args->requirements && args->requirements != PANFROST_JD_REQ_FS)
+ if (args->requirements & ~JOB_REQUIREMENTS)
return -EINVAL;
if (args->out_sync > 0) {
@@ -551,10 +589,12 @@ static void panfrost_gpu_show_fdinfo(struct panfrost_device *pfdev,
BUILD_BUG_ON(ARRAY_SIZE(engine_names) != NUM_JOB_SLOTS);
for (i = 0; i < NUM_JOB_SLOTS - 1; i++) {
- drm_printf(p, "drm-engine-%s:\t%llu ns\n",
- engine_names[i], panfrost_priv->engine_usage.elapsed_ns[i]);
- drm_printf(p, "drm-cycles-%s:\t%llu\n",
- engine_names[i], panfrost_priv->engine_usage.cycles[i]);
+ if (pfdev->profile_mode) {
+ drm_printf(p, "drm-engine-%s:\t%llu ns\n",
+ engine_names[i], panfrost_priv->engine_usage.elapsed_ns[i]);
+ drm_printf(p, "drm-cycles-%s:\t%llu\n",
+ engine_names[i], panfrost_priv->engine_usage.cycles[i]);
+ }
drm_printf(p, "drm-maxfreq-%s:\t%lu Hz\n",
engine_names[i], pfdev->pfdevfreq.fast_rate);
drm_printf(p, "drm-curfreq-%s:\t%lu Hz\n",
@@ -583,6 +623,8 @@ static const struct file_operations panfrost_drm_driver_fops = {
* - 1.0 - initial interface
* - 1.1 - adds HEAP and NOEXEC flags for CREATE_BO
* - 1.2 - adds AFBC_FEATURES query
+ * - 1.3 - adds JD_REQ_CYCLE_COUNT job requirement for SUBMIT
+ * - adds SYSTEM_TIMESTAMP and SYSTEM_TIMESTAMP_FREQUENCY queries
*/
static const struct drm_driver panfrost_drm_driver = {
.driver_features = DRIVER_RENDER | DRIVER_GEM | DRIVER_SYNCOBJ,
@@ -594,16 +636,11 @@ static const struct drm_driver panfrost_drm_driver = {
.fops = &panfrost_drm_driver_fops,
.name = "panfrost",
.desc = "panfrost DRM",
- .date = "20180908",
.major = 1,
- .minor = 2,
+ .minor = 3,
.gem_create_object = panfrost_gem_create_object,
.gem_prime_import_sg_table = panfrost_gem_prime_import_sg_table,
-
-#ifdef CONFIG_DEBUG_FS
- .debugfs_init = panfrost_debugfs_init,
-#endif
};
static int panfrost_probe(struct platform_device *pdev)
@@ -692,6 +729,40 @@ static void panfrost_remove(struct platform_device *pdev)
drm_dev_put(ddev);
}
+static ssize_t profiling_show(struct device *dev,
+ struct device_attribute *attr, char *buf)
+{
+ struct panfrost_device *pfdev = dev_get_drvdata(dev);
+
+ return sysfs_emit(buf, "%d\n", pfdev->profile_mode);
+}
+
+static ssize_t profiling_store(struct device *dev,
+ struct device_attribute *attr,
+ const char *buf, size_t len)
+{
+ struct panfrost_device *pfdev = dev_get_drvdata(dev);
+ bool value;
+ int err;
+
+ err = kstrtobool(buf, &value);
+ if (err)
+ return err;
+
+ pfdev->profile_mode = value;
+
+ return len;
+}
+
+static DEVICE_ATTR_RW(profiling);
+
+static struct attribute *panfrost_attrs[] = {
+ &dev_attr_profiling.attr,
+ NULL,
+};
+
+ATTRIBUTE_GROUPS(panfrost);
+
/*
* The OPP core wants the supply names to be NULL terminated, but we need the
* correct num_supplies value for regulator core. Hence, we NULL terminate here
@@ -746,6 +817,15 @@ static const struct panfrost_compatible mediatek_mt8186_data = {
.pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF),
};
+/* MT8188 uses the same power domains and power supplies as MT8183 */
+static const struct panfrost_compatible mediatek_mt8188_data = {
+ .num_supplies = ARRAY_SIZE(mediatek_mt8183_b_supplies) - 1,
+ .supply_names = mediatek_mt8183_b_supplies,
+ .num_pm_domains = ARRAY_SIZE(mediatek_mt8183_pm_domains),
+ .pm_domain_names = mediatek_mt8183_pm_domains,
+ .pm_features = BIT(GPU_PM_CLK_DIS) | BIT(GPU_PM_VREG_OFF),
+};
+
static const char * const mediatek_mt8192_supplies[] = { "mali", NULL };
static const char * const mediatek_mt8192_pm_domains[] = { "core0", "core1", "core2",
"core3", "core4" };
@@ -777,6 +857,7 @@ static const struct of_device_id dt_match[] = {
{ .compatible = "mediatek,mt8183-mali", .data = &mediatek_mt8183_data },
{ .compatible = "mediatek,mt8183b-mali", .data = &mediatek_mt8183_b_data },
{ .compatible = "mediatek,mt8186-mali", .data = &mediatek_mt8186_data },
+ { .compatible = "mediatek,mt8188-mali", .data = &mediatek_mt8188_data },
{ .compatible = "mediatek,mt8192-mali", .data = &mediatek_mt8192_data },
{}
};
@@ -784,11 +865,12 @@ MODULE_DEVICE_TABLE(of, dt_match);
static struct platform_driver panfrost_driver = {
.probe = panfrost_probe,
- .remove_new = panfrost_remove,
+ .remove = panfrost_remove,
.driver = {
.name = "panfrost",
.pm = pm_ptr(&panfrost_pm_ops),
.of_match_table = dt_match,
+ .dev_groups = panfrost_groups,
},
};
module_platform_driver(panfrost_driver);
@@ -796,3 +878,4 @@ module_platform_driver(panfrost_driver);
MODULE_AUTHOR("Panfrost Project Developers");
MODULE_DESCRIPTION("Panfrost DRM Driver");
MODULE_LICENSE("GPL v2");
+MODULE_SOFTDEP("pre: governor_simpleondemand");