build/patch/kernel/rk322x-current/01-linux-0022-drm-from-next.patch
paolo bd17d4dbd0 Many changes for rk322x target:
- Chanaged default x.org configuration to disable glamor
- Reintroduce patch to use DRM cursor plane as overlay in rk322x-current and -dev
- Updated wifi patches for kernel 5.8.10
- Bumped rk322x to u-boot v2020.07, removed reserved zones from device trees
- Updated OPTEE to v3.10, using ddrbin v1.10
- Bumped rk322x-current to kernel 5.8.y
- Imported new patches from knaerzche's LibreELEC fork for rk322x-dev (kernel 5.8.y)
- Adjusted existing patches to match changes, updated rk322x-dev kernel config file
- Add default modprobe conf file for esp8089 to force the crystal frequency to 40Mhz for rk322x targets
- Removed ssv6051 firmware packages to move to armbian-firmware repository
- Switching ssv6051-wifi.cfg to /lib/firmware for rk322x-legacy
- Removed P2P interface for esp8089 driver for rk322x-legacy
- Optimized ssv6051 performance: kernel module gains -Os flag, disabled p2p interface, enabled HW crypto for CCMP cipher
- Enabled remote control interface, IR GPIO kernel module and HDMI CEC modules
2020-09-19 15:20:16 +00:00

1276 lines
43 KiB
Diff

From 055013808487a12514bd6a10d5f1be4267d3cf4a Mon Sep 17 00:00:00 2001
From: Neil Armstrong <narmstrong@baylibre.com>
Date: Thu, 23 Jul 2020 11:05:50 +0200
Subject: [PATCH] drm/fourcc: fix Amlogic Video Framebuffer Compression macro
Fix the Amlogic Video Framebuffer Compression modifier macro to
correctly add the layout options, a pair of parenthesis was missing.
Fixes: d6528ec88309 ("drm/fourcc: Add modifier definitions for describing Amlogic Video Framebuffer Compression")
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Acked-by: Sam Ravnborg <sam@ravnborg.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200723090551.27529-1-narmstrong@baylibre.com
(cherry picked from commit da3a9e9a6aa96ef589c153078f66e0646bf06b55)
---
include/uapi/drm/drm_fourcc.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/uapi/drm/drm_fourcc.h b/include/uapi/drm/drm_fourcc.h
index 4bee7de5f306..82f327801267 100644
--- a/include/uapi/drm/drm_fourcc.h
+++ b/include/uapi/drm/drm_fourcc.h
@@ -1004,7 +1004,7 @@ drm_fourcc_canonicalize_nvidia_format_mod(__u64 modifier)
#define DRM_FORMAT_MOD_AMLOGIC_FBC(__layout, __options) \
fourcc_mod_code(AMLOGIC, \
((__layout) & __fourcc_mod_amlogic_layout_mask) | \
- ((__options) & __fourcc_mod_amlogic_options_mask \
+ (((__options) & __fourcc_mod_amlogic_options_mask) \
<< __fourcc_mod_amlogic_options_shift))
/* Amlogic FBC Layouts */
From 9df4c74d07ec7d3141b2a243b49de48f3e36932b Mon Sep 17 00:00:00 2001
From: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Date: Thu, 11 Jun 2020 10:58:43 +0200
Subject: [PATCH] drm/panfrost: Make sure GPU is powered on when reading
GPU_LATEST_FLUSH_ID
Bifrost devices do support the flush reduction feature, so on first job
submit we were trying to read the register while still powered off.
If the GPU is powered off, the feature doesn't bring any benefit, so
don't try to read.
Tested-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Steven Price <steven.price@arm.com>
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200611085900.49740-1-tomeu.vizoso@collabora.com
(cherry picked from commit 3a74265c54f883c847ed8554129baefb3e04f135)
---
drivers/gpu/drm/panfrost/panfrost_gpu.c | 14 ++++++++++++--
1 file changed, 12 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_gpu.c b/drivers/gpu/drm/panfrost/panfrost_gpu.c
index f2c1ddc41a9b..e0f190e43813 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gpu.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gpu.c
@@ -10,6 +10,7 @@
#include <linux/io.h>
#include <linux/iopoll.h>
#include <linux/platform_device.h>
+#include <linux/pm_runtime.h>
#include "panfrost_device.h"
#include "panfrost_features.h"
@@ -368,7 +369,16 @@ void panfrost_gpu_fini(struct panfrost_device *pfdev)
u32 panfrost_gpu_get_latest_flush_id(struct panfrost_device *pfdev)
{
- if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION))
- return gpu_read(pfdev, GPU_LATEST_FLUSH_ID);
+ u32 flush_id;
+
+ if (panfrost_has_hw_feature(pfdev, HW_FEATURE_FLUSH_REDUCTION)) {
+ /* Flush reduction only makes sense when the GPU is kept powered on between jobs */
+ if (pm_runtime_get_if_in_use(pfdev->dev)) {
+ flush_id = gpu_read(pfdev, GPU_LATEST_FLUSH_ID);
+ pm_runtime_put(pfdev->dev);
+ return flush_id;
+ }
+ }
+
return 0;
}
From 956be03f3fc751937bbb07a4e4201a2a73aa87f1 Mon Sep 17 00:00:00 2001
From: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Date: Thu, 11 Jun 2020 10:58:44 +0200
Subject: [PATCH] drm/panfrost: Add compatible string for bifrost
Mesa now supports some Bifrost devices, so enable it.
Tested-by: Heiko Stuebner <heiko@sntech.de>
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Heiko Stuebner <heiko@sntech.de>
Signed-off-by: Tomeu Vizoso <tomeu.vizoso@collabora.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200611085900.49740-2-tomeu.vizoso@collabora.com
(cherry picked from commit 72ef7fe96fd20d3d0e538e165b393819f99870ad)
---
drivers/gpu/drm/panfrost/panfrost_drv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 882fecc33fdb..8ff8e140f91e 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -677,6 +677,7 @@ static const struct of_device_id dt_match[] = {
{ .compatible = "arm,mali-t830", .data = &default_data, },
{ .compatible = "arm,mali-t860", .data = &default_data, },
{ .compatible = "arm,mali-t880", .data = &default_data, },
+ { .compatible = "arm,mali-bifrost", .data = &default_data, },
{}
};
MODULE_DEVICE_TABLE(of, dt_match);
From 1404f107a58a28fb71227550469c4785fa58081c Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
Date: Fri, 10 Jul 2020 11:53:56 +0200
Subject: [PATCH] drm/panfrost: avoid static declaration
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This declaration can be avoided so change it.
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-2-peron.clem@gmail.com
(cherry picked from commit 862cc626210e34501b4d7a7795c41a67785987e5)
---
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 38 ++++++++++-----------
1 file changed, 18 insertions(+), 20 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 413987038fbf..1b560b903ea6 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -14,7 +14,24 @@
#include "panfrost_gpu.h"
#include "panfrost_regs.h"
-static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev);
+static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev)
+{
+ ktime_t now;
+ ktime_t last;
+
+ if (!pfdev->devfreq.devfreq)
+ return;
+
+ now = ktime_get();
+ last = pfdev->devfreq.time_last_update;
+
+ if (atomic_read(&pfdev->devfreq.busy_count) > 0)
+ pfdev->devfreq.busy_time += ktime_sub(now, last);
+ else
+ pfdev->devfreq.idle_time += ktime_sub(now, last);
+
+ pfdev->devfreq.time_last_update = now;
+}
static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,
u32 flags)
@@ -139,25 +156,6 @@ void panfrost_devfreq_suspend(struct panfrost_device *pfdev)
devfreq_suspend_device(pfdev->devfreq.devfreq);
}
-static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev)
-{
- ktime_t now;
- ktime_t last;
-
- if (!pfdev->devfreq.devfreq)
- return;
-
- now = ktime_get();
- last = pfdev->devfreq.time_last_update;
-
- if (atomic_read(&pfdev->devfreq.busy_count) > 0)
- pfdev->devfreq.busy_time += ktime_sub(now, last);
- else
- pfdev->devfreq.idle_time += ktime_sub(now, last);
-
- pfdev->devfreq.time_last_update = now;
-}
-
void panfrost_devfreq_record_busy(struct panfrost_device *pfdev)
{
panfrost_devfreq_update_utilization(pfdev);
From 42e45c3c4195d8e7ebe5bf970c7da55fc9c0d157 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
Date: Fri, 10 Jul 2020 11:53:57 +0200
Subject: [PATCH] drm/panfrost: clean headers in devfreq
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Don't include not required headers and sort them.
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-3-peron.clem@gmail.com
(cherry picked from commit 9713e942a539c55b5e0bc64ba83b736bda1087fe)
---
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 1b560b903ea6..df7b71da9a84 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -1,18 +1,14 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright 2019 Collabora ltd. */
+
+#include <linux/clk.h>
#include <linux/devfreq.h>
#include <linux/devfreq_cooling.h>
#include <linux/platform_device.h>
#include <linux/pm_opp.h>
-#include <linux/clk.h>
-#include <linux/regulator/consumer.h>
#include "panfrost_device.h"
#include "panfrost_devfreq.h"
-#include "panfrost_features.h"
-#include "panfrost_issues.h"
-#include "panfrost_gpu.h"
-#include "panfrost_regs.h"
static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev)
{
From 99fda3d26b30e5f30d45fc6197da6335a2806e73 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
Date: Fri, 10 Jul 2020 11:53:58 +0200
Subject: [PATCH] drm/panfrost: don't use pfdevfreq.busy_count to know if hw is
idle
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
This use devfreq variable that will be lock with spinlock in future
patches. We should either introduce a function to access this one
but as devfreq is optional let's just remove it.
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-4-peron.clem@gmail.com
(cherry picked from commit eb9dd67249b55fd1fa3d7359be387ea2079247a6)
---
drivers/gpu/drm/panfrost/panfrost_job.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c
index c6242fe34840..aec05be1ba7a 100644
--- a/drivers/gpu/drm/panfrost/panfrost_job.c
+++ b/drivers/gpu/drm/panfrost/panfrost_job.c
@@ -581,10 +581,6 @@ int panfrost_job_is_idle(struct panfrost_device *pfdev)
struct panfrost_job_slot *js = pfdev->js;
int i;
- /* Check whether the hardware is idle */
- if (atomic_read(&pfdev->devfreq.busy_count))
- return false;
-
for (i = 0; i < NUM_JOB_SLOTS; i++) {
/* If there are any jobs in the HW queue, we're not idle */
if (atomic_read(&js->queue[i].sched.hw_rq_count))
From ca3fb7080e5fbaf5894bed7e119e8f4e49545449 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
Date: Fri, 10 Jul 2020 11:53:59 +0200
Subject: [PATCH] drm/panfrost: introduce panfrost_devfreq struct
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduce a proper panfrost_devfreq to deal with devfreq variables.
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-5-peron.clem@gmail.com
(cherry picked from commit 9bfacfc82f903b066b0b63460d5b7943705048a4)
---
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 76 ++++++++++++---------
drivers/gpu/drm/panfrost/panfrost_devfreq.h | 20 +++++-
drivers/gpu/drm/panfrost/panfrost_device.h | 11 +--
drivers/gpu/drm/panfrost/panfrost_job.c | 6 +-
4 files changed, 66 insertions(+), 47 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index df7b71da9a84..962550363391 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -10,23 +10,23 @@
#include "panfrost_device.h"
#include "panfrost_devfreq.h"
-static void panfrost_devfreq_update_utilization(struct panfrost_device *pfdev)
+static void panfrost_devfreq_update_utilization(struct panfrost_devfreq *pfdevfreq)
{
ktime_t now;
ktime_t last;
- if (!pfdev->devfreq.devfreq)
+ if (!pfdevfreq->devfreq)
return;
now = ktime_get();
- last = pfdev->devfreq.time_last_update;
+ last = pfdevfreq->time_last_update;
- if (atomic_read(&pfdev->devfreq.busy_count) > 0)
- pfdev->devfreq.busy_time += ktime_sub(now, last);
+ if (atomic_read(&pfdevfreq->busy_count) > 0)
+ pfdevfreq->busy_time += ktime_sub(now, last);
else
- pfdev->devfreq.idle_time += ktime_sub(now, last);
+ pfdevfreq->idle_time += ktime_sub(now, last);
- pfdev->devfreq.time_last_update = now;
+ pfdevfreq->time_last_update = now;
}
static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,
@@ -47,30 +47,31 @@ static int panfrost_devfreq_target(struct device *dev, unsigned long *freq,
return 0;
}
-static void panfrost_devfreq_reset(struct panfrost_device *pfdev)
+static void panfrost_devfreq_reset(struct panfrost_devfreq *pfdevfreq)
{
- pfdev->devfreq.busy_time = 0;
- pfdev->devfreq.idle_time = 0;
- pfdev->devfreq.time_last_update = ktime_get();
+ pfdevfreq->busy_time = 0;
+ pfdevfreq->idle_time = 0;
+ pfdevfreq->time_last_update = ktime_get();
}
static int panfrost_devfreq_get_dev_status(struct device *dev,
struct devfreq_dev_status *status)
{
struct panfrost_device *pfdev = dev_get_drvdata(dev);
+ struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
- panfrost_devfreq_update_utilization(pfdev);
+ panfrost_devfreq_update_utilization(pfdevfreq);
status->current_frequency = clk_get_rate(pfdev->clock);
- status->total_time = ktime_to_ns(ktime_add(pfdev->devfreq.busy_time,
- pfdev->devfreq.idle_time));
+ status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time,
+ pfdevfreq->idle_time));
- status->busy_time = ktime_to_ns(pfdev->devfreq.busy_time);
+ status->busy_time = ktime_to_ns(pfdevfreq->busy_time);
- panfrost_devfreq_reset(pfdev);
+ panfrost_devfreq_reset(pfdevfreq);
- dev_dbg(pfdev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n", status->busy_time,
- status->total_time,
+ dev_dbg(pfdev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n",
+ status->busy_time, status->total_time,
status->busy_time / (status->total_time / 100),
status->current_frequency / 1000 / 1000);
@@ -91,6 +92,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
struct device *dev = &pfdev->pdev->dev;
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
+ struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
ret = dev_pm_opp_of_add_table(dev);
if (ret == -ENODEV) /* Optional, continue without devfreq */
@@ -98,7 +100,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
else if (ret)
return ret;
- panfrost_devfreq_reset(pfdev);
+ panfrost_devfreq_reset(pfdevfreq);
cur_freq = clk_get_rate(pfdev->clock);
@@ -116,53 +118,59 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
dev_pm_opp_of_remove_table(dev);
return PTR_ERR(devfreq);
}
- pfdev->devfreq.devfreq = devfreq;
+ pfdevfreq->devfreq = devfreq;
cooling = of_devfreq_cooling_register(dev->of_node, devfreq);
if (IS_ERR(cooling))
DRM_DEV_INFO(dev, "Failed to register cooling device\n");
else
- pfdev->devfreq.cooling = cooling;
+ pfdevfreq->cooling = cooling;
return 0;
}
void panfrost_devfreq_fini(struct panfrost_device *pfdev)
{
- if (pfdev->devfreq.cooling)
- devfreq_cooling_unregister(pfdev->devfreq.cooling);
+ struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
+
+ if (pfdevfreq->cooling)
+ devfreq_cooling_unregister(pfdevfreq->cooling);
dev_pm_opp_of_remove_table(&pfdev->pdev->dev);
}
void panfrost_devfreq_resume(struct panfrost_device *pfdev)
{
- if (!pfdev->devfreq.devfreq)
+ struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
+
+ if (!pfdevfreq->devfreq)
return;
- panfrost_devfreq_reset(pfdev);
+ panfrost_devfreq_reset(pfdevfreq);
- devfreq_resume_device(pfdev->devfreq.devfreq);
+ devfreq_resume_device(pfdevfreq->devfreq);
}
void panfrost_devfreq_suspend(struct panfrost_device *pfdev)
{
- if (!pfdev->devfreq.devfreq)
+ struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
+
+ if (!pfdevfreq->devfreq)
return;
- devfreq_suspend_device(pfdev->devfreq.devfreq);
+ devfreq_suspend_device(pfdevfreq->devfreq);
}
-void panfrost_devfreq_record_busy(struct panfrost_device *pfdev)
+void panfrost_devfreq_record_busy(struct panfrost_devfreq *pfdevfreq)
{
- panfrost_devfreq_update_utilization(pfdev);
- atomic_inc(&pfdev->devfreq.busy_count);
+ panfrost_devfreq_update_utilization(pfdevfreq);
+ atomic_inc(&pfdevfreq->busy_count);
}
-void panfrost_devfreq_record_idle(struct panfrost_device *pfdev)
+void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq)
{
int count;
- panfrost_devfreq_update_utilization(pfdev);
- count = atomic_dec_if_positive(&pfdev->devfreq.busy_count);
+ panfrost_devfreq_update_utilization(pfdevfreq);
+ count = atomic_dec_if_positive(&pfdevfreq->busy_count);
WARN_ON(count < 0);
}
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
index 0611beffc8d0..0697f8d5aa34 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
@@ -4,13 +4,29 @@
#ifndef __PANFROST_DEVFREQ_H__
#define __PANFROST_DEVFREQ_H__
+#include <linux/ktime.h>
+
+struct devfreq;
+struct thermal_cooling_device;
+
+struct panfrost_device;
+
+struct panfrost_devfreq {
+ struct devfreq *devfreq;
+ struct thermal_cooling_device *cooling;
+ ktime_t busy_time;
+ ktime_t idle_time;
+ ktime_t time_last_update;
+ atomic_t busy_count;
+};
+
int panfrost_devfreq_init(struct panfrost_device *pfdev);
void panfrost_devfreq_fini(struct panfrost_device *pfdev);
void panfrost_devfreq_resume(struct panfrost_device *pfdev);
void panfrost_devfreq_suspend(struct panfrost_device *pfdev);
-void panfrost_devfreq_record_busy(struct panfrost_device *pfdev);
-void panfrost_devfreq_record_idle(struct panfrost_device *pfdev);
+void panfrost_devfreq_record_busy(struct panfrost_devfreq *devfreq);
+void panfrost_devfreq_record_idle(struct panfrost_devfreq *devfreq);
#endif /* __PANFROST_DEVFREQ_H__ */
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h
index c30c719a8059..2efa59c9d1c5 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -13,6 +13,8 @@
#include <drm/drm_mm.h>
#include <drm/gpu_scheduler.h>
+#include "panfrost_devfreq.h"
+
struct panfrost_device;
struct panfrost_mmu;
struct panfrost_job_slot;
@@ -107,14 +109,7 @@ struct panfrost_device {
struct list_head shrinker_list;
struct shrinker shrinker;
- struct {
- struct devfreq *devfreq;
- struct thermal_cooling_device *cooling;
- ktime_t busy_time;
- ktime_t idle_time;
- ktime_t time_last_update;
- atomic_t busy_count;
- } devfreq;
+ struct panfrost_devfreq pfdevfreq;
};
struct panfrost_mmu {
diff --git a/drivers/gpu/drm/panfrost/panfrost_job.c b/drivers/gpu/drm/panfrost/panfrost_job.c
index aec05be1ba7a..2f297d962e64 100644
--- a/drivers/gpu/drm/panfrost/panfrost_job.c
+++ b/drivers/gpu/drm/panfrost/panfrost_job.c
@@ -145,7 +145,7 @@ static void panfrost_job_hw_submit(struct panfrost_job *job, int js)
u64 jc_head = job->jc;
int ret;
- panfrost_devfreq_record_busy(pfdev);
+ panfrost_devfreq_record_busy(&pfdev->pfdevfreq);
ret = pm_runtime_get_sync(pfdev->dev);
if (ret < 0)
@@ -410,7 +410,7 @@ static void panfrost_job_timedout(struct drm_sched_job *sched_job)
for (i = 0; i < NUM_JOB_SLOTS; i++) {
if (pfdev->jobs[i]) {
pm_runtime_put_noidle(pfdev->dev);
- panfrost_devfreq_record_idle(pfdev);
+ panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
pfdev->jobs[i] = NULL;
}
}
@@ -478,7 +478,7 @@ static irqreturn_t panfrost_job_irq_handler(int irq, void *data)
pfdev->jobs[j] = NULL;
panfrost_mmu_as_put(pfdev, &job->file_priv->mmu);
- panfrost_devfreq_record_idle(pfdev);
+ panfrost_devfreq_record_idle(&pfdev->pfdevfreq);
dma_fence_signal_locked(job->done_fence);
pm_runtime_put_autosuspend(pfdev->dev);
From 950ed8f4f8c6ab02e5f1c7b107e5af9a896c90dc Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
Date: Fri, 10 Jul 2020 11:54:00 +0200
Subject: [PATCH] drm/panfrost: use spinlock instead of atomic
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Convert busy_count to a simple int protected by spinlock.
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-6-peron.clem@gmail.com
(cherry picked from commit ed85df3f60740bb4be23fbc2db283d59b361a834)
---
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 43 +++++++++++++++------
drivers/gpu/drm/panfrost/panfrost_devfreq.h | 9 ++++-
2 files changed, 40 insertions(+), 12 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 962550363391..78753cfb59fb 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -12,16 +12,12 @@
static void panfrost_devfreq_update_utilization(struct panfrost_devfreq *pfdevfreq)
{
- ktime_t now;
- ktime_t last;
-
- if (!pfdevfreq->devfreq)
- return;
+ ktime_t now, last;
now = ktime_get();
last = pfdevfreq->time_last_update;
- if (atomic_read(&pfdevfreq->busy_count) > 0)
+ if (pfdevfreq->busy_count > 0)
pfdevfreq->busy_time += ktime_sub(now, last);
else
pfdevfreq->idle_time += ktime_sub(now, last);
@@ -59,10 +55,14 @@ static int panfrost_devfreq_get_dev_status(struct device *dev,
{
struct panfrost_device *pfdev = dev_get_drvdata(dev);
struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
+ unsigned long irqflags;
+
+ status->current_frequency = clk_get_rate(pfdev->clock);
+
+ spin_lock_irqsave(&pfdevfreq->lock, irqflags);
panfrost_devfreq_update_utilization(pfdevfreq);
- status->current_frequency = clk_get_rate(pfdev->clock);
status->total_time = ktime_to_ns(ktime_add(pfdevfreq->busy_time,
pfdevfreq->idle_time));
@@ -70,6 +70,8 @@ static int panfrost_devfreq_get_dev_status(struct device *dev,
panfrost_devfreq_reset(pfdevfreq);
+ spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
+
dev_dbg(pfdev->dev, "busy %lu total %lu %lu %% freq %lu MHz\n",
status->busy_time, status->total_time,
status->busy_time / (status->total_time / 100),
@@ -100,6 +102,8 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
else if (ret)
return ret;
+ spin_lock_init(&pfdevfreq->lock);
+
panfrost_devfreq_reset(pfdevfreq);
cur_freq = clk_get_rate(pfdev->clock);
@@ -162,15 +166,32 @@ void panfrost_devfreq_suspend(struct panfrost_device *pfdev)
void panfrost_devfreq_record_busy(struct panfrost_devfreq *pfdevfreq)
{
+ unsigned long irqflags;
+
+ if (!pfdevfreq->devfreq)
+ return;
+
+ spin_lock_irqsave(&pfdevfreq->lock, irqflags);
+
panfrost_devfreq_update_utilization(pfdevfreq);
- atomic_inc(&pfdevfreq->busy_count);
+
+ pfdevfreq->busy_count++;
+
+ spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
}
void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq)
{
- int count;
+ unsigned long irqflags;
+
+ if (!pfdevfreq->devfreq)
+ return;
+
+ spin_lock_irqsave(&pfdevfreq->lock, irqflags);
panfrost_devfreq_update_utilization(pfdevfreq);
- count = atomic_dec_if_positive(&pfdevfreq->busy_count);
- WARN_ON(count < 0);
+
+ WARN_ON(--pfdevfreq->busy_count < 0);
+
+ spin_unlock_irqrestore(&pfdevfreq->lock, irqflags);
}
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
index 0697f8d5aa34..3392df1020be 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
@@ -4,6 +4,7 @@
#ifndef __PANFROST_DEVFREQ_H__
#define __PANFROST_DEVFREQ_H__
+#include <linux/spinlock.h>
#include <linux/ktime.h>
struct devfreq;
@@ -14,10 +15,16 @@ struct panfrost_device;
struct panfrost_devfreq {
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
+
ktime_t busy_time;
ktime_t idle_time;
ktime_t time_last_update;
- atomic_t busy_count;
+ int busy_count;
+ /*
+ * Protect busy_time, idle_time, time_last_update and busy_count
+ * because these can be updated concurrently between multiple jobs.
+ */
+ spinlock_t lock;
};
int panfrost_devfreq_init(struct panfrost_device *pfdev);
From ac548872c7b7887d34b549efa3b8334b2cc862ed Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
Date: Fri, 10 Jul 2020 11:54:01 +0200
Subject: [PATCH] drm/panfrost: properly handle error in probe
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Introduce a boolean to know if opp table has been added.
With this, we can call panfrost_devfreq_fini() in case of error
and release what has been initialised.
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-7-peron.clem@gmail.com
(cherry picked from commit 81f2fbe62cb54b6cf3d91078c4d49451ba7b9877)
---
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 25 ++++++++++++++++-----
drivers/gpu/drm/panfrost/panfrost_devfreq.h | 1 +
2 files changed, 20 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 78753cfb59fb..d9007f44b772 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -101,6 +101,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
return 0;
else if (ret)
return ret;
+ pfdevfreq->opp_of_table_added = true;
spin_lock_init(&pfdevfreq->lock);
@@ -109,8 +110,10 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
cur_freq = clk_get_rate(pfdev->clock);
opp = devfreq_recommended_opp(dev, &cur_freq, 0);
- if (IS_ERR(opp))
- return PTR_ERR(opp);
+ if (IS_ERR(opp)) {
+ ret = PTR_ERR(opp);
+ goto err_fini;
+ }
panfrost_devfreq_profile.initial_freq = cur_freq;
dev_pm_opp_put(opp);
@@ -119,8 +122,8 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
DEVFREQ_GOV_SIMPLE_ONDEMAND, NULL);
if (IS_ERR(devfreq)) {
DRM_DEV_ERROR(dev, "Couldn't initialize GPU devfreq\n");
- dev_pm_opp_of_remove_table(dev);
- return PTR_ERR(devfreq);
+ ret = PTR_ERR(devfreq);
+ goto err_fini;
}
pfdevfreq->devfreq = devfreq;
@@ -131,15 +134,25 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
pfdevfreq->cooling = cooling;
return 0;
+
+err_fini:
+ panfrost_devfreq_fini(pfdev);
+ return ret;
}
void panfrost_devfreq_fini(struct panfrost_device *pfdev)
{
struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
- if (pfdevfreq->cooling)
+ if (pfdevfreq->cooling) {
devfreq_cooling_unregister(pfdevfreq->cooling);
- dev_pm_opp_of_remove_table(&pfdev->pdev->dev);
+ pfdevfreq->cooling = NULL;
+ }
+
+ if (pfdevfreq->opp_of_table_added) {
+ dev_pm_opp_of_remove_table(&pfdev->pdev->dev);
+ pfdevfreq->opp_of_table_added = false;
+ }
}
void panfrost_devfreq_resume(struct panfrost_device *pfdev)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
index 3392df1020be..210269944687 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
@@ -15,6 +15,7 @@ struct panfrost_device;
struct panfrost_devfreq {
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
+ bool opp_of_table_added;
ktime_t busy_time;
ktime_t idle_time;
From 96a752deaead8b45cd188cde09cb873fd8dfd4b6 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
Date: Fri, 10 Jul 2020 11:54:02 +0200
Subject: [PATCH] drm/panfrost: rename error labels in device_init
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Rename goto labels in device_init it will be easier to maintain.
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-8-peron.clem@gmail.com
(cherry picked from commit d3c335da0200be9287cdf5755d19f62ce1670a8d)
---
drivers/gpu/drm/panfrost/panfrost_device.c | 30 +++++++++++-----------
1 file changed, 15 insertions(+), 15 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
index b172087eee6a..9f89984f652a 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -216,56 +216,56 @@ int panfrost_device_init(struct panfrost_device *pfdev)
err = panfrost_regulator_init(pfdev);
if (err)
- goto err_out0;
+ goto out_clk;
err = panfrost_reset_init(pfdev);
if (err) {
dev_err(pfdev->dev, "reset init failed %d\n", err);
- goto err_out1;
+ goto out_regulator;
}
err = panfrost_pm_domain_init(pfdev);
if (err)
- goto err_out2;
+ goto out_reset;
res = platform_get_resource(pfdev->pdev, IORESOURCE_MEM, 0);
pfdev->iomem = devm_ioremap_resource(pfdev->dev, res);
if (IS_ERR(pfdev->iomem)) {
dev_err(pfdev->dev, "failed to ioremap iomem\n");
err = PTR_ERR(pfdev->iomem);
- goto err_out3;
+ goto out_pm_domain;
}
err = panfrost_gpu_init(pfdev);
if (err)
- goto err_out3;
+ goto out_pm_domain;
err = panfrost_mmu_init(pfdev);
if (err)
- goto err_out4;
+ goto out_gpu;
err = panfrost_job_init(pfdev);
if (err)
- goto err_out5;
+ goto out_mmu;
err = panfrost_perfcnt_init(pfdev);
if (err)
- goto err_out6;
+ goto out_job;
return 0;
-err_out6:
+out_job:
panfrost_job_fini(pfdev);
-err_out5:
+out_mmu:
panfrost_mmu_fini(pfdev);
-err_out4:
+out_gpu:
panfrost_gpu_fini(pfdev);
-err_out3:
+out_pm_domain:
panfrost_pm_domain_fini(pfdev);
-err_out2:
+out_reset:
panfrost_reset_fini(pfdev);
-err_out1:
+out_regulator:
panfrost_regulator_fini(pfdev);
-err_out0:
+out_clk:
panfrost_clk_fini(pfdev);
return err;
}
From 9c803e01258f241d49e1162ca6db5b29a98ba57d Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
Date: Fri, 10 Jul 2020 11:54:03 +0200
Subject: [PATCH] drm/panfrost: move devfreq_init()/fini() in device
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Later we will introduce devfreq probing regulator if they
are present. As regulator should be probe only one time we
need to get this logic in the device_init().
panfrost_device is already taking care of devfreq_resume()
and devfreq_suspend(), so it's not totally illogic to move
the devfreq_init() and devfreq_fini() here.
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Reviewed-by: Steven Price <steven.price@arm.com>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-9-peron.clem@gmail.com
(cherry picked from commit 25e247bbf85af3ad721dfeb2e2caf405f43b7e66)
---
drivers/gpu/drm/panfrost/panfrost_device.c | 12 +++++++++++-
drivers/gpu/drm/panfrost/panfrost_drv.c | 15 ++-------------
2 files changed, 13 insertions(+), 14 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
index 9f89984f652a..36b5c8fea3eb 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -214,9 +214,16 @@ int panfrost_device_init(struct panfrost_device *pfdev)
return err;
}
+ err = panfrost_devfreq_init(pfdev);
+ if (err) {
+ if (err != -EPROBE_DEFER)
+ dev_err(pfdev->dev, "devfreq init failed %d\n", err);
+ goto out_clk;
+ }
+
err = panfrost_regulator_init(pfdev);
if (err)
- goto out_clk;
+ goto out_devfreq;
err = panfrost_reset_init(pfdev);
if (err) {
@@ -265,6 +272,8 @@ int panfrost_device_init(struct panfrost_device *pfdev)
panfrost_reset_fini(pfdev);
out_regulator:
panfrost_regulator_fini(pfdev);
+out_devfreq:
+ panfrost_devfreq_fini(pfdev);
out_clk:
panfrost_clk_fini(pfdev);
return err;
@@ -278,6 +287,7 @@ void panfrost_device_fini(struct panfrost_device *pfdev)
panfrost_gpu_fini(pfdev);
panfrost_pm_domain_fini(pfdev);
panfrost_reset_fini(pfdev);
+ panfrost_devfreq_fini(pfdev);
panfrost_regulator_fini(pfdev);
panfrost_clk_fini(pfdev);
}
diff --git a/drivers/gpu/drm/panfrost/panfrost_drv.c b/drivers/gpu/drm/panfrost/panfrost_drv.c
index 8ff8e140f91e..ed8bcdd6b211 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -14,7 +14,6 @@
#include <drm/drm_utils.h>
#include "panfrost_device.h"
-#include "panfrost_devfreq.h"
#include "panfrost_gem.h"
#include "panfrost_mmu.h"
#include "panfrost_job.h"
@@ -606,13 +605,6 @@ static int panfrost_probe(struct platform_device *pdev)
goto err_out0;
}
- err = panfrost_devfreq_init(pfdev);
- if (err) {
- if (err != -EPROBE_DEFER)
- dev_err(&pdev->dev, "Fatal error during devfreq init\n");
- goto err_out1;
- }
-
pm_runtime_set_active(pfdev->dev);
pm_runtime_mark_last_busy(pfdev->dev);
pm_runtime_enable(pfdev->dev);
@@ -625,16 +617,14 @@ static int panfrost_probe(struct platform_device *pdev)
*/
err = drm_dev_register(ddev, 0);
if (err < 0)
- goto err_out2;
+ goto err_out1;
panfrost_gem_shrinker_init(ddev);
return 0;
-err_out2:
- pm_runtime_disable(pfdev->dev);
- panfrost_devfreq_fini(pfdev);
err_out1:
+ pm_runtime_disable(pfdev->dev);
panfrost_device_fini(pfdev);
err_out0:
drm_dev_put(ddev);
@@ -650,7 +640,6 @@ static int panfrost_remove(struct platform_device *pdev)
panfrost_gem_shrinker_cleanup(ddev);
pm_runtime_get_sync(pfdev->dev);
- panfrost_devfreq_fini(pfdev);
panfrost_device_fini(pfdev);
pm_runtime_put_sync_suspend(pfdev->dev);
pm_runtime_disable(pfdev->dev);
From d858649520907e147d85147efb8cfdb280ee5852 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
Date: Fri, 10 Jul 2020 11:54:04 +0200
Subject: [PATCH] drm/panfrost: dynamically alloc regulators
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
We will later introduce regulators managed by OPP.
Only alloc regulators when it's needed. This also help use
to release the regulators only when they are allocated.
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-10-peron.clem@gmail.com
(cherry picked from commit 512f21227fd3d2dbe7aad57a995b9732229c9b56)
---
drivers/gpu/drm/panfrost/panfrost_device.c | 14 +++++++++-----
drivers/gpu/drm/panfrost/panfrost_device.h | 3 +--
2 files changed, 10 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
index 36b5c8fea3eb..f1474b961def 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -90,9 +90,11 @@ static int panfrost_regulator_init(struct panfrost_device *pfdev)
{
int ret, i;
- if (WARN(pfdev->comp->num_supplies > ARRAY_SIZE(pfdev->regulators),
- "Too many supplies in compatible structure.\n"))
- return -EINVAL;
+ pfdev->regulators = devm_kcalloc(pfdev->dev, pfdev->comp->num_supplies,
+ sizeof(*pfdev->regulators),
+ GFP_KERNEL);
+ if (!pfdev->regulators)
+ return -ENOMEM;
for (i = 0; i < pfdev->comp->num_supplies; i++)
pfdev->regulators[i].supply = pfdev->comp->supply_names[i];
@@ -119,8 +121,10 @@ static int panfrost_regulator_init(struct panfrost_device *pfdev)
static void panfrost_regulator_fini(struct panfrost_device *pfdev)
{
- regulator_bulk_disable(pfdev->comp->num_supplies,
- pfdev->regulators);
+ if (!pfdev->regulators)
+ return;
+
+ regulator_bulk_disable(pfdev->comp->num_supplies, pfdev->regulators);
}
static void panfrost_pm_domain_fini(struct panfrost_device *pfdev)
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.h b/drivers/gpu/drm/panfrost/panfrost_device.h
index 2efa59c9d1c5..953f7536a773 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.h
+++ b/drivers/gpu/drm/panfrost/panfrost_device.h
@@ -22,7 +22,6 @@ struct panfrost_job;
struct panfrost_perfcnt;
#define NUM_JOB_SLOTS 3
-#define MAX_REGULATORS 2
#define MAX_PM_DOMAINS 3
struct panfrost_features {
@@ -81,7 +80,7 @@ struct panfrost_device {
void __iomem *iomem;
struct clk *clock;
struct clk *bus_clock;
- struct regulator_bulk_data regulators[MAX_REGULATORS];
+ struct regulator_bulk_data *regulators;
struct reset_control *rstc;
/* pm_domains for devices with more than one. */
struct device *pm_domain_devs[MAX_PM_DOMAINS];
From 1ee7aed7c3c6736b33828d488a6d29bd8f0e0e84 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Cl=C3=A9ment=20P=C3=A9ron?= <peron.clem@gmail.com>
Date: Fri, 10 Jul 2020 11:54:05 +0200
Subject: [PATCH] drm/panfrost: add regulators to devfreq
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit
Some OPP tables specify voltage for each frequency. Devfreq can
handle these regulators but they should be get only 1 time to avoid
issue and know who is in charge.
If OPP table is probe don't init regulator.
Reviewed-by: Steven Price <steven.price@arm.com>
Reviewed-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Clément Péron <peron.clem@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200710095409.407087-11-peron.clem@gmail.com
(cherry picked from commit fd587ff01d59554144e2fd20f4113638a45c7c4e)
---
drivers/gpu/drm/panfrost/panfrost_devfreq.c | 29 ++++++++++++++++++---
drivers/gpu/drm/panfrost/panfrost_devfreq.h | 2 ++
drivers/gpu/drm/panfrost/panfrost_device.c | 9 ++++---
3 files changed, 33 insertions(+), 7 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index d9007f44b772..8ab025d0035f 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -93,14 +93,30 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
unsigned long cur_freq;
struct device *dev = &pfdev->pdev->dev;
struct devfreq *devfreq;
+ struct opp_table *opp_table;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = &pfdev->pfdevfreq;
+ opp_table = dev_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
+ pfdev->comp->num_supplies);
+ if (IS_ERR(opp_table)) {
+ ret = PTR_ERR(opp_table);
+ /* Continue if the optional regulator is missing */
+ if (ret != -ENODEV) {
+ DRM_DEV_ERROR(dev, "Couldn't set OPP regulators\n");
+ goto err_fini;
+ }
+ } else {
+ pfdevfreq->regulators_opp_table = opp_table;
+ }
+
ret = dev_pm_opp_of_add_table(dev);
- if (ret == -ENODEV) /* Optional, continue without devfreq */
- return 0;
- else if (ret)
- return ret;
+ if (ret) {
+ /* Optional, continue without devfreq */
+ if (ret == -ENODEV)
+ ret = 0;
+ goto err_fini;
+ }
pfdevfreq->opp_of_table_added = true;
spin_lock_init(&pfdevfreq->lock);
@@ -153,6 +169,11 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev)
dev_pm_opp_of_remove_table(&pfdev->pdev->dev);
pfdevfreq->opp_of_table_added = false;
}
+
+ if (pfdevfreq->regulators_opp_table) {
+ dev_pm_opp_put_regulators(pfdevfreq->regulators_opp_table);
+ pfdevfreq->regulators_opp_table = NULL;
+ }
}
void panfrost_devfreq_resume(struct panfrost_device *pfdev)
diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
index 210269944687..db6ea48e21f9 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
@@ -8,12 +8,14 @@
#include <linux/ktime.h>
struct devfreq;
+struct opp_table;
struct thermal_cooling_device;
struct panfrost_device;
struct panfrost_devfreq {
struct devfreq *devfreq;
+ struct opp_table *regulators_opp_table;
struct thermal_cooling_device *cooling;
bool opp_of_table_added;
diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c b/drivers/gpu/drm/panfrost/panfrost_device.c
index f1474b961def..e6896733838a 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -225,9 +225,12 @@ int panfrost_device_init(struct panfrost_device *pfdev)
goto out_clk;
}
- err = panfrost_regulator_init(pfdev);
- if (err)
- goto out_devfreq;
+ /* OPP will handle regulators */
+ if (!pfdev->pfdevfreq.opp_of_table_added) {
+ err = panfrost_regulator_init(pfdev);
+ if (err)
+ goto out_devfreq;
+ }
err = panfrost_reset_init(pfdev);
if (err) {
From 94b3398f3b4d5e963f284bd39515bfdf84530c6c Mon Sep 17 00:00:00 2001
From: Navid Emamdoost <navid.emamdoost@gmail.com>
Date: Sun, 14 Jun 2020 01:36:19 -0500
Subject: [PATCH] drm/panfrost: perfcnt: fix ref count leak in
panfrost_perfcnt_enable_locked
in panfrost_perfcnt_enable_locked, pm_runtime_get_sync is called which
increments the counter even in case of failure, leading to incorrect
ref count. In case of failure, decrement the ref count before returning.
Acked-by: Alyssa Rosenzweig <alyssa.rosenzweig@collabora.com>
Signed-off-by: Navid Emamdoost <navid.emamdoost@gmail.com>
Signed-off-by: Rob Herring <robh@kernel.org>
Link: https://patchwork.freedesktop.org/patch/msgid/20200614063619.44944-1-navid.emamdoost@gmail.com
(cherry picked from commit 9df0e0c1889677175037445d5ad1654d54176369)
---
drivers/gpu/drm/panfrost/panfrost_perfcnt.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c
index 6913578d5aa7..6169644d4469 100644
--- a/drivers/gpu/drm/panfrost/panfrost_perfcnt.c
+++ b/drivers/gpu/drm/panfrost/panfrost_perfcnt.c
@@ -83,11 +83,13 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
ret = pm_runtime_get_sync(pfdev->dev);
if (ret < 0)
- return ret;
+ goto err_put_pm;
bo = drm_gem_shmem_create(pfdev->ddev, perfcnt->bosize);
- if (IS_ERR(bo))
- return PTR_ERR(bo);
+ if (IS_ERR(bo)) {
+ ret = PTR_ERR(bo);
+ goto err_put_pm;
+ }
/* Map the perfcnt buf in the address space attached to file_priv. */
ret = panfrost_gem_open(&bo->base, file_priv);
@@ -168,6 +170,8 @@ static int panfrost_perfcnt_enable_locked(struct panfrost_device *pfdev,
panfrost_gem_close(&bo->base, file_priv);
err_put_bo:
drm_gem_object_put_unlocked(&bo->base);
+err_put_pm:
+ pm_runtime_put(pfdev->dev);
return ret;
}