Re: [PATCH v3 06/14] drm/panthor: Add the devfreq logical block

2023-12-05 Thread Clément Péron
Hi Boris,

On Mon, 4 Dec 2023 at 18:33, Boris Brezillon
 wrote:
>
> Every thing related to devfreq in placed in panthor_devfreq.c, and
> helpers that can be called by other logical blocks are exposed through
> panthor_devfreq.h.
>
> This implementation is loosely based on the panfrost implementation,
> the only difference being that we don't count device users, because
> the idle/active state will be managed by the scheduler logic.
>
> v3:
> - Add acks for the MIT/GPL2 relicensing
>
> v2:
> - Added in v2
>
> Cc: Clément Péron  # MIT+GPL2 relicensing

For the MIT+GPL2 relicensing.

Acked-by: Clément Péron 

> Reviewed-by: Steven Price 
> Signed-off-by: Boris Brezillon 
> Acked-by: Steven Price  # MIT+GPL2 relicensing,Arm
> Acked-by: Grant Likely  # MIT+GPL2 relicensing,Linaro
> Acked-by: Boris Brezillon  # MIT+GPL2 
> relicensing,Collabora
> ---
>  drivers/gpu/drm/panthor/panthor_devfreq.c | 283 ++
>  drivers/gpu/drm/panthor/panthor_devfreq.h |  25 ++
>  2 files changed, 308 insertions(+)
>  create mode 100644 drivers/gpu/drm/panthor/panthor_devfreq.c
>  create mode 100644 drivers/gpu/drm/panthor/panthor_devfreq.h
>
> diff --git a/drivers/gpu/drm/panthor/panthor_devfreq.c 
> b/drivers/gpu/drm/panthor/panthor_devfreq.c
> new file mode 100644
> index ..dd28b15337d4
> --- /dev/null
> +++ b/drivers/gpu/drm/panthor/panthor_devfreq.c
> @@ -0,0 +1,283 @@
> +// SPDX-License-Identifier: GPL-2.0 or MIT
> +/* Copyright 2019 Collabora ltd. */
> +
> +#include 
> +#include 
> +#include 
> +#include 
> +#include 
> +
> +#include 
> +
> +#include "panthor_device.h"
> +#include "panthor_devfreq.h"
> +
> +/**
> + * struct panthor_devfreq - Device frequency management
> + */
> +struct panthor_devfreq {
> +   /** @devfreq: devfreq device. */
> +   struct devfreq *devfreq;
> +
> +   /** @gov_data: Governor data. */
> +   struct devfreq_simple_ondemand_data gov_data;
> +
> +   /** @busy_time: Busy time. */
> +   ktime_t busy_time;
> +
> +   /** @idle_time: Idle time. */
> +   ktime_t idle_time;
> +
> +   /** @time_last_update: Last update time. */
> +   ktime_t time_last_update;
> +
> +   /** @last_busy_state: True if the GPU was busy last time we updated 
> the state. */
> +   bool last_busy_state;
> +
> +   /*
> +* @lock: Lock used to protect busy_time, idle_time, time_last_update 
> and
> +* last_busy_state.
> +*
> +* These fields can be accessed concurrently by 
> panthor_devfreq_get_dev_status()
> +* and panthor_devfreq_record_{busy,idle}().
> +*/
> +   spinlock_t lock;
> +};
> +
> +static void panthor_devfreq_update_utilization(struct panthor_devfreq 
> *pdevfreq)
> +{
> +   ktime_t now, last;
> +
> +   now = ktime_get();
> +   last = pdevfreq->time_last_update;
> +
> +   if (pdevfreq->last_busy_state)
> +   pdevfreq->busy_time += ktime_sub(now, last);
> +   else
> +   pdevfreq->idle_time += ktime_sub(now, last);
> +
> +   pdevfreq->time_last_update = now;
> +}
> +
> +static int panthor_devfreq_target(struct device *dev, unsigned long *freq,
> + u32 flags)
> +{
> +   struct dev_pm_opp *opp;
> +
> +   opp = devfreq_recommended_opp(dev, freq, flags);
> +   if (IS_ERR(opp))
> +   return PTR_ERR(opp);
> +   dev_pm_opp_put(opp);
> +
> +   return dev_pm_opp_set_rate(dev, *freq);
> +}
> +
> +static void panthor_devfreq_reset(struct panthor_devfreq *pdevfreq)
> +{
> +   pdevfreq->busy_time = 0;
> +   pdevfreq->idle_time = 0;
> +   pdevfreq->time_last_update = ktime_get();
> +}
> +
> +static int panthor_devfreq_get_dev_status(struct device *dev,
> + struct devfreq_dev_status *status)
> +{
> +   struct panthor_device *ptdev = dev_get_drvdata(dev);
> +   struct panthor_devfreq *pdevfreq = ptdev->devfreq;
> +   unsigned long irqflags;
> +
> +   status->current_frequency = clk_get_rate(ptdev->clks.core);
> +
> +   spin_lock_irqsave(>lock, irqflags);
> +
> +   panthor_devfreq_update_utilization(pdevfreq);
> +
> +   status->total_time = ktime_to_ns(ktime_add(pdevfreq->busy_time,
> +  pdevfreq->idle_time));
> +
> +   status->busy_time = ktime_to_ns(pdevfreq->busy_time);
> +
> +   panthor_devfreq_reset(pdevfreq);
> +
> +   spin_unlock_irqrestore(>

Re: [PATCH v3 00/14] drm: Add a driver for CSF-based Mali GPUs

2023-12-04 Thread Clément Péron
Hi Boris,

On Mon, 4 Dec 2023 at 18:33, Boris Brezillon
 wrote:
>
> Hello,
>
> This is the 3rd version of the kernel driver for Mali CSF-based GPUs.
>
> With all the DRM dependencies being merged (drm-sched single entity and
> drm_gpuvm), I thought now was a good time to post a new version. Note
> that the iommu series we depend on [1] has been merged recently. The
> only remaining dependency that hasn't been merged yet is this rather
> trival drm_gpuvm [2] patch.
>
> As for v2, I pushed a branch based on drm-misc-next and containing
> all the dependencies that are not yet available in drm-misc-next
> here[3], and another [4] containing extra patches to have things
> working on rk3588. The CSF firmware binary can be found here[5], and
> should be placed under /lib/firmware/arm/mali/arch10.8/mali_csffw.bin.
>
> The mesa MR adding v10 support on top of panthor is available here [6].
>
> Regarding the GPL2+MIT relicensing, Liviu did an audit and found two
> more people that I didn't spot initially: Clément Péron for the devfreq
> code, and Alexey Sheplyakov for some bits in panthor_gpu.c. Both are
> Cc-ed on the relevant patches. The rest of the code is either new, or
> covered by the Linaro, Arm and Collabora acks.

I only did some trivial cleaning, the relicensing is fine for me.
Do you need me to ack some patches?

Regards,
Clement

>
> And here is a non-exhaustive changelog, check each commit for a detailed
> changelog.
>
> v3;
> - Quite a few changes at the MMU/sched level to make the fix some
>   race conditions and deadlocks
> - Addition of the a sync-only VM_BIND operation (to support
>   vkQueueSparseBind with zero commands).
> - Addition of a VM_GET_STATE ioctl
> - Various cosmetic changes (see the commit changelogs for more details)
> - Various fixes (see the commit changelogs for more details)
>
> v2:
> - Rename the driver (pancsf -> panthor)
> - Split the commit adding the driver to ease review
> - Use drm_sched for dependency tracking/job submission
> - Add a VM_BIND ioctl
> - Add the concept of exclusive VM for BOs that are only ever mapped to a
>   single VM
> - Document the code and uAPI
> - Add a DT binding doc
>
> Regards,
>
> Boris
>
> [1]https://lore.kernel.org/linux-arm-kernel/20231124142434.1577550-1-boris.brezil...@collabora.com/T/
> [2]https://patchwork.freedesktop.org/patch/570380/
> [3]https://gitlab.freedesktop.org/panfrost/linux/-/tree/panthor-v3
> [4]https://gitlab.freedesktop.org/panfrost/linux/-/tree/panthor-v3+rk3588
> [5]https://gitlab.com/firefly-linux/external/libmali/-/raw/firefly/firmware/g610/mali_csffw.bin
> [6]https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/26358
>
> Boris Brezillon (13):
>   drm/panthor: Add uAPI
>   drm/panthor: Add GPU register definitions
>   drm/panthor: Add the device logical block
>   drm/panthor: Add the GPU logical block
>   drm/panthor: Add GEM logical block
>   drm/panthor: Add the devfreq logical block
>   drm/panthor: Add the MMU/VM logical block
>   drm/panthor: Add the FW logical block
>   drm/panthor: Add the heap logical block
>   drm/panthor: Add the scheduler logical block
>   drm/panthor: Add the driver frontend block
>   drm/panthor: Allow driver compilation
>   drm/panthor: Add an entry to MAINTAINERS
>
> Liviu Dudau (1):
>   dt-bindings: gpu: mali-valhall-csf: Add support for Arm Mali CSF GPUs
>
>  .../bindings/gpu/arm,mali-valhall-csf.yaml|  147 +
>  Documentation/gpu/driver-uapi.rst |5 +
>  MAINTAINERS   |   11 +
>  drivers/gpu/drm/Kconfig   |2 +
>  drivers/gpu/drm/Makefile  |1 +
>  drivers/gpu/drm/panthor/Kconfig   |   23 +
>  drivers/gpu/drm/panthor/Makefile  |   15 +
>  drivers/gpu/drm/panthor/panthor_devfreq.c |  283 ++
>  drivers/gpu/drm/panthor/panthor_devfreq.h |   25 +
>  drivers/gpu/drm/panthor/panthor_device.c  |  497 +++
>  drivers/gpu/drm/panthor/panthor_device.h  |  381 ++
>  drivers/gpu/drm/panthor/panthor_drv.c | 1454 +++
>  drivers/gpu/drm/panthor/panthor_fw.c  | 1332 +++
>  drivers/gpu/drm/panthor/panthor_fw.h  |  504 +++
>  drivers/gpu/drm/panthor/panthor_gem.c |  227 ++
>  drivers/gpu/drm/panthor/panthor_gem.h |  144 +
>  drivers/gpu/drm/panthor/panthor_gpu.c |  481 +++
>  drivers/gpu/drm/panthor/panthor_gpu.h |   52 +
>  drivers/gpu/drm/panthor/panthor_heap.c|  517 +++
>  drivers/gpu/drm/panthor/panthor_heap.h|   36 +
>  drivers/gpu/drm/panthor/panthor_mmu.c | 2653 +
>  drivers/gpu/drm/panthor/panthor_mmu.h |  101 +
>  drivers/gpu/drm/panthor/panthor_regs.h  

Re: [PATCH v4 3/5] arm64: dts: allwinner: h6: Add GPU OPP table

2022-09-06 Thread Clément Péron
Hi Jernej,

On Tue, 6 Sept 2022 at 21:10, Jernej Škrabec  wrote:
>
> Dne torek, 06. september 2022 ob 17:30:32 CEST je Clément Péron napisal(a):
> > Add an Operating Performance Points table for the GPU to
> > enable Dynamic Voltage & Frequency Scaling on the H6.
> >
> > The voltage range is set with minimal voltage set to the target
> > and the maximal voltage set to 1.2V. This allow DVFS framework to
> > work properly on board with fixed regulator.
> >
> > Signed-off-by: Clément Péron 
> > ---
> >  .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 +++
> >  1 file changed, 87 insertions(+)
> >  create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> > b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi new file mode 100644
> > index ..b48049c4fc85
> > --- /dev/null
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
> > @@ -0,0 +1,87 @@
> > +// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
> > +// Copyright (C) 2022 Clément Péron 
> > +
> > +/ {
> > + gpu_opp_table: opp-table-gpu {
> > + compatible = "operating-points-v2";
> > +
> > + opp-21600 {
> > + opp-hz = /bits/ 64 <21600>;
> > + opp-microvolt = <81 81 120>;
> > + };
> > +
> > + opp-26400 {
> > + opp-hz = /bits/ 64 <26400>;
> > + opp-microvolt = <81 81 120>;
> > + };
>
> As mentioned in clock patch review, rates below 288 MHz are deemed unstable on
> GPU PLL by vendor GPU kernel driver. At least in the BSP version that I have.
> Did you test these points? If not, better to drop them.

I changed the governor to userspace and set the freq to 216MHz / 264MHz
Run glmark2 and didn't observe any glitch nor issue.

I'm not sure if it's enough to say it's stable but I didn't observe
any strange behavior.

Regards,
Clement

>
> Best regards,
> Jernej
>
> > +
> > + opp-31200 {
> > + opp-hz = /bits/ 64 <31200>;
> > + opp-microvolt = <81 81 120>;
> > + };
> > +
> > + opp-33600 {
> > + opp-hz = /bits/ 64 <33600>;
> > + opp-microvolt = <81 81 120>;
> > + };
> > +
> > + opp-36000 {
> > + opp-hz = /bits/ 64 <36000>;
> > + opp-microvolt = <82 82 120>;
> > + };
> > +
> > + opp-38400 {
> > + opp-hz = /bits/ 64 <38400>;
> > + opp-microvolt = <83 83 120>;
> > + };
> > +
> > + opp-40800 {
> > + opp-hz = /bits/ 64 <40800>;
> > + opp-microvolt = <84 84 120>;
> > + };
> > +
> > + opp-42000 {
> > + opp-hz = /bits/ 64 <42000>;
> > + opp-microvolt = <85 85 120>;
> > + };
> > +
> > + opp-43200 {
> > + opp-hz = /bits/ 64 <43200>;
> > + opp-microvolt = <86 86 120>;
> > + };
> > +
> > + opp-45600 {
> > + opp-hz = /bits/ 64 <45600>;
> > + opp-microvolt = <87 87 120>;
> > + };
> > +
> > + opp-50400 {
> > + opp-hz = /bits/ 64 <50400>;
> > + opp-microvolt = <89 89 120>;
> > + };
> > +
> > + opp-54000 {
> > + opp-hz = /bits/ 64 <54000>;
> > + opp-microvolt = <91 91 120>;
> > + };
> > +
> > + opp-57600 {
> > + opp-hz = /bits/ 64 <57600>;
> > + opp-microvolt = <93 93 120>;
> > + };
> > +
> > + opp-62400 {
> > + opp-hz = /bits/ 64 <62400>;
> > + opp-microvolt = <95 95 120>;
> > + };
> > +
> > + opp-75600 {
> > + opp-hz = /bits/ 64 <75600>;
> > + opp-microvolt = <104 104 120>;
> > + };
> > + };
> > +};
> > +
> > + {
> > + operating-points-v2 = <_opp_table>;
> > +};
> > --
> > 2.34.1
>
>


[PATCH v4 5/5] arm64: dts: allwinner: beelink-gs1: Enable GPU OPP

2022-09-06 Thread Clément Péron
Enable GPU OPP table for Beelink GS1.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
index 6249e9e02928..9ec49ac2f6fd 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
@@ -5,6 +5,7 @@
 
 #include "sun50i-h6.dtsi"
 #include "sun50i-h6-cpu-opp.dtsi"
+#include "sun50i-h6-gpu-opp.dtsi"
 
 #include 
 
-- 
2.34.1



[PATCH v4 1/5] arm64: defconfig: Enable devfreq cooling device

2022-09-06 Thread Clément Péron
Devfreq cooling device framework is used in Panfrost
to throttle GPU in order to regulate its temperature.

Enable this driver for ARM64 SoC.

Signed-off-by: Clément Péron 
Acked-by: Jernej Skrabec 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 91e58cf59c99..e557ccac8d9c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -582,6 +582,7 @@ CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_INA3221=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
 CONFIG_IMX_SC_THERMAL=m
 CONFIG_IMX8MM_THERMAL=m
-- 
2.34.1



[PATCH v4 2/5] arm64: dts: allwinner: h6: Add cooling map for GPU

2022-09-06 Thread Clément Péron
Add a simple cooling map for the GPU.

This cooling map come from the vendor kernel 4.9 with a
2°C hysteresis added.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 51 +++-
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 5a28303d3d4c..53f6660656ac 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -186,6 +186,7 @@ gpu: gpu@180 {
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   #cooling-cells = <2>;
status = "disabled";
};
 
@@ -1072,9 +1073,55 @@ map0 {
};
 
gpu-thermal {
-   polling-delay-passive = <0>;
-   polling-delay = <0>;
+   polling-delay-passive = <1000>;
+   polling-delay = <2000>;
thermal-sensors = < 1>;
+
+   trips {
+   gpu_alert0: gpu-alert-0 {
+   temperature = <95000>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu_alert1: gpu-alert-1 {
+   temperature = <10>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu_alert2: gpu-alert-2 {
+   temperature = <105000>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu-crit {
+   temperature = <115000>;
+   hysteresis = <0>;
+   type = "critical";
+   };
+   };
+
+   cooling-maps {
+   // Forbid the GPU to go over 756MHz
+   map0 {
+   trip = <_alert0>;
+   cooling-device = < 1 
THERMAL_NO_LIMIT>;
+   };
+
+   // Forbid the GPU to go over 624MHz
+   map1 {
+   trip = <_alert1>;
+   cooling-device = < 2 
THERMAL_NO_LIMIT>;
+   };
+
+   // Forbid the GPU to go over 576MHz
+   map2 {
+   trip = <_alert2>;
+   cooling-device = < 3 
THERMAL_NO_LIMIT>;
+   };
+   };
};
};
 };
-- 
2.34.1



[PATCH v4 3/5] arm64: dts: allwinner: h6: Add GPU OPP table

2022-09-06 Thread Clément Péron
Add an Operating Performance Points table for the GPU to
enable Dynamic Voltage & Frequency Scaling on the H6.

The voltage range is set with minimal voltage set to the target
and the maximal voltage set to 1.2V. This allow DVFS framework to
work properly on board with fixed regulator.

Signed-off-by: Clément Péron 
---
 .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 +++
 1 file changed, 87 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
new file mode 100644
index ..b48049c4fc85
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2022 Clément Péron 
+
+/ {
+   gpu_opp_table: opp-table-gpu {
+   compatible = "operating-points-v2";
+
+   opp-21600 {
+   opp-hz = /bits/ 64 <21600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp-26400 {
+   opp-hz = /bits/ 64 <26400>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp-31200 {
+   opp-hz = /bits/ 64 <31200>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp-33600 {
+   opp-hz = /bits/ 64 <33600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp-36000 {
+   opp-hz = /bits/ 64 <36000>;
+   opp-microvolt = <82 82 120>;
+   };
+
+   opp-38400 {
+   opp-hz = /bits/ 64 <38400>;
+   opp-microvolt = <83 83 120>;
+   };
+
+   opp-40800 {
+   opp-hz = /bits/ 64 <40800>;
+   opp-microvolt = <84 84 120>;
+   };
+
+   opp-42000 {
+   opp-hz = /bits/ 64 <42000>;
+   opp-microvolt = <85 85 120>;
+   };
+
+   opp-43200 {
+   opp-hz = /bits/ 64 <43200>;
+   opp-microvolt = <86 86 120>;
+   };
+
+   opp-45600 {
+   opp-hz = /bits/ 64 <45600>;
+   opp-microvolt = <87 87 120>;
+   };
+
+   opp-50400 {
+   opp-hz = /bits/ 64 <50400>;
+   opp-microvolt = <89 89 120>;
+   };
+
+   opp-54000 {
+   opp-hz = /bits/ 64 <54000>;
+   opp-microvolt = <91 91 120>;
+   };
+
+   opp-57600 {
+   opp-hz = /bits/ 64 <57600>;
+   opp-microvolt = <93 93 120>;
+   };
+
+   opp-62400 {
+   opp-hz = /bits/ 64 <62400>;
+   opp-microvolt = <95 95 120>;
+   };
+
+   opp-75600 {
+   opp-hz = /bits/ 64 <75600>;
+   opp-microvolt = <104 104 120>;
+   };
+   };
+};
+
+ {
+   operating-points-v2 = <_opp_table>;
+};
-- 
2.34.1



[PATCH v4 4/5] drm/panfrost: devfreq: set opp to the recommended one to configure regulator

2022-09-06 Thread Clément Péron
Enabling panfrost GPU OPP with dynamic regulator will make OPP
responsible to enable and configure it.

Unfortunatly OPP configure and enable the regulator when an OPP
is asked to be set, which is not the case during
panfrost_devfreq_init().

This leave the regulator unconfigured and if no GPU load is
triggered, no OPP is asked to be set which make the regulator framework
switching it off during regulator_late_cleanup() without
noticing and therefore make the board hang as any access to GPU
memory space make bus locks up.

Call dev_pm_opp_set_opp() with the recommend OPP in
panfrost_devfreq_init() to enable the regulator, this will properly
configure and enable the regulator and will avoid any switch off
by regulator_late_cleanup().

Suggested-by: Viresh Kumar 
Signed-off-by: Clément Péron 
---
 drivers/gpu/drm/panfrost/panfrost_devfreq.c | 11 +++
 1 file changed, 11 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c 
b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 5110cd9b2425..fe5f12f16a63 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -131,6 +131,17 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
return PTR_ERR(opp);
 
panfrost_devfreq_profile.initial_freq = cur_freq;
+
+   /*
+* Set the recommend OPP this will enable and configure the regulator
+* if any and will avoid a switch off by regulator_late_cleanup()
+*/
+   ret = dev_pm_opp_set_opp(dev, opp);
+   if (ret) {
+   DRM_DEV_ERROR(dev, "Couldn't set recommended OPP\n");
+   return ret;
+   }
+
dev_pm_opp_put(opp);
 
/*
-- 
2.34.1



[PATCH v4 0/5] Allwinner H6 GPU devfreq

2022-09-06 Thread Clément Péron
Hi,

This is a refresh of previous patches sent to enable GPU Devfreq on H6
Beelink GS1 but that wasn't stable at that time[0].

With the recent fix on GPU PLL from Roman Stratiienko I have retested
and everything seems stable and works as expected[1].

Regards,
Clement

0: 
https://lore.kernel.org/lkml/cajiucce58gaxf_qg2cnmwvoguqyu__ekb3mdx1fe_+47htg...@mail.gmail.com/
1: https://lore.kernel.org/linux-arm-kernel/2562485.k3LOHGUjKi@kista/T/

Changes since v3:
 - Try to be more explicit for panfrost OPP patch
 - Fix typo

Changes since v2:
 - Fixes device-tree warnings
 - Add panfrost fix to enable regulator
 - Remove always-on regulator from device-tree
 - Update cooling map from vendor kernel


Clément Péron (5):
  arm64: defconfig: Enable devfreq cooling device
  arm64: dts: allwinner: h6: Add cooling map for GPU
  arm64: dts: allwinner: h6: Add GPU OPP table
  drm/panfrost: devfreq: set opp to the recommended one to configure
regulator
  arm64: dts: allwinner: beelink-gs1: Enable GPU OPP

 .../dts/allwinner/sun50i-h6-beelink-gs1.dts   |  1 +
 .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 +++
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 51 ++-
 arch/arm64/configs/defconfig  |  1 +
 drivers/gpu/drm/panfrost/panfrost_devfreq.c   | 11 +++
 5 files changed, 149 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi

-- 
2.34.1



Re: [PATCH v3 4/5] drm/panfrost: devfreq: set opp to the recommended one to configure and enable regulator

2022-09-06 Thread Clément Péron
Hi,

On Tue, 6 Sept 2022 at 10:06, Biju Das  wrote:
>
> Hi Clement,
>
> > Subject: Re: [PATCH v3 4/5] drm/panfrost: devfreq: set opp to the
> > recommended one to configure and enable regulator
> >
> > Hi Biju,
> >
> > On Tue, 6 Sept 2022 at 08:42, Biju Das 
> > wrote:
> > >
> > > Hi Clement,
> > >
> > > >
> > > > Hi,
> > > >
> > > > On Mon, 5 Sept 2022 at 20:17, Biju Das 
> > > > wrote:
> > > > >
> > > > > Hi,
> > > > >
> > > > > Thanks for the patch.
> > > > >
> > > > > > Subject: [PATCH v3 4/5] drm/panfrost: devfreq: set opp to the
> > > > > > recommended one to configure and enable regulator
> > > > > >
> > > > > > devm_pm_opp_set_regulators() doesn't enable regulator, which
> > > > > > make regulator framework switching it off during
> > regulator_late_cleanup().
> > > > >
> > > > > In that case, why not regulator_get()for Dynamic regulator(non
> > > > > fixed regulator)??
> > > >
> > > > Sorry I don't understand, what do you mean?
> > >
> > > Normally we need to turn on regulator and clock only when needed.
> > > I am not sure with your new code, will make it always on and drains
> > > the power unnecessarily and does it set lower opp or higher opp at the
> > > start??
> >
> > The code doesn't make it always on, it makes it how it should be at the
> > recommended OPP which is the "start point".
> >
> > If the recommended OPP says to switch off the regulator then it will.
> >
> > >
> > > Compared to the fixed regulator, you have voltage regulator to control
> > > that is the difference between my environment and Your environment.
> > >
> > > I am not sure any other SoC is using voltage regulator??
> > > If yes, thenthere should be some bug or some difference in HW which is
> > > giving different behaviour??
> > >
> > > If you are the first one using voltage regulator with mali gpu, Then
> > > Your implementation may be correct, as you have proper HW to check.
> >
> > The issue is that my regulator is not marked as "always-on", if no OPP is
> > called before regulator_late_cleanup() then nobody sets the
> > regulator_enable() and the regulator is switched off, which makes my
> > board hang.
>
> Cool, From your testing looks like no one tested this feature with
> mali GPU on mainline??

Or no one without always-on.

Clement

>
> Cheers,
> Biju
>
>
> >
> > Like Viresh recommends I will send an update with more details in the
> > commit log.
> >
> > Regards,
> > Clement
> >
> >
> > >
> > > >
> > > > >
> > > > > >
> > > > > > Call dev_pm_opp_set_opp() with the recommend OPP in
> > > > > > panfrost_devfreq_init() to enable the regulator and avoid any
> > > > > > switch off by regulator_late_cleanup().
> > > > > >
> > > > > > Suggested-by: Viresh Kumar 
> > > > > > Signed-off-by: Clément Péron 
> > > > > > ---
> > > > > >  drivers/gpu/drm/panfrost/panfrost_devfreq.c | 8 
> > > > > >  1 file changed, 8 insertions(+)
> > > > > >
> > > > > > diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > > > > > b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > > > > > index 5110cd9b2425..67b242407156 100644
> > > > > > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > > > > > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > > > > > @@ -131,6 +131,14 @@ int panfrost_devfreq_init(struct
> > > > > > panfrost_device
> > > > > > *pfdev)
> > > > > >   return PTR_ERR(opp);
> > > > > >
> > > > > >   panfrost_devfreq_profile.initial_freq = cur_freq;
> > > > > > +
> > > > > > + /* Setup and enable regulator */
> > > > > > + ret = dev_pm_opp_set_opp(dev, opp);
> > > > > > + if (ret) {
> > > > > > + DRM_DEV_ERROR(dev, "Couldn't set recommended
> > OPP\n");
> > > > > > + return ret;
> > > > > > + }
> > > > >
> &

Re: [PATCH v3 4/5] drm/panfrost: devfreq: set opp to the recommended one to configure and enable regulator

2022-09-06 Thread Clément Péron
Hi Biju,

On Tue, 6 Sept 2022 at 08:42, Biju Das  wrote:
>
> Hi Clement,
>
> >
> > Hi,
> >
> > On Mon, 5 Sept 2022 at 20:17, Biju Das 
> > wrote:
> > >
> > > Hi,
> > >
> > > Thanks for the patch.
> > >
> > > > Subject: [PATCH v3 4/5] drm/panfrost: devfreq: set opp to the
> > > > recommended one to configure and enable regulator
> > > >
> > > > devm_pm_opp_set_regulators() doesn't enable regulator, which make
> > > > regulator framework switching it off during regulator_late_cleanup().
> > >
> > > In that case, why not regulator_get()for Dynamic regulator(non fixed
> > > regulator)??
> >
> > Sorry I don't understand, what do you mean?
>
> Normally we need to turn on regulator and clock only when needed.
> I am not sure with your new code, will make it always on and
> drains the power unnecessarily and does it set lower opp or higher
> opp at the start??

The code doesn't make it always on, it makes it how it should be at
the recommended OPP which is the "start point".

If the recommended OPP says to switch off the regulator then it will.

>
> Compared to the fixed regulator, you have voltage regulator to
> control that is the difference between my environment and
> Your environment.
>
> I am not sure any other SoC is using voltage regulator??
> If yes, thenthere should be some bug or some difference in HW
> which is giving different behaviour??
>
> If you are the first one using voltage regulator with mali gpu,
> Then Your implementation may be correct, as you have proper
> HW to check.

The issue is that my regulator is not marked as "always-on", if no OPP
is called before regulator_late_cleanup() then nobody sets the
regulator_enable() and the regulator is switched off, which makes my
board hang.

Like Viresh recommends I will send an update with more details in the
commit log.

Regards,
Clement


>
> >
> > >
> > > >
> > > > Call dev_pm_opp_set_opp() with the recommend OPP in
> > > > panfrost_devfreq_init() to enable the regulator and avoid any switch
> > > > off by regulator_late_cleanup().
> > > >
> > > > Suggested-by: Viresh Kumar 
> > > > Signed-off-by: Clément Péron 
> > > > ---
> > > >  drivers/gpu/drm/panfrost/panfrost_devfreq.c | 8 
> > > >  1 file changed, 8 insertions(+)
> > > >
> > > > diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > > > b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > > > index 5110cd9b2425..67b242407156 100644
> > > > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > > > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > > > @@ -131,6 +131,14 @@ int panfrost_devfreq_init(struct
> > > > panfrost_device
> > > > *pfdev)
> > > >   return PTR_ERR(opp);
> > > >
> > > >   panfrost_devfreq_profile.initial_freq = cur_freq;
> > > > +
> > > > + /* Setup and enable regulator */
> > > > + ret = dev_pm_opp_set_opp(dev, opp);
> > > > + if (ret) {
> > > > + DRM_DEV_ERROR(dev, "Couldn't set recommended OPP\n");
> > > > + return ret;
> > > > + }
> > >
> > >
> > > FYI,
> > > On RZ/G2L mali gpu, we have fixed regulator and I was able to do GPU
> > > OPP transition without any issues previously.
> >
> > rzg2l-smarc-som.dtsi uses regulator reg_1p1v; which is marked as
> > regulator-always-on; that's why
> > regulator_late_cleanup() doesn't switch it off.
>
> Yes that is correct. It is fixed regulator and always on.
> We control only frequency.
>
> Cheers,
> Biju
>
> >
> > >
> > > root@smarc-rzg2l:~# cat /sys/class/devfreq/1184.gpu/trans_stat
> > >  From  :   To
> > >:  5000  6250 1 12500 2
> > 25000 4 5   time(ms)
> > > *  5000: 0 0 0 0 0
> > 0 0 1   144
> > >6250: 0 0 0 0 0
> > 0 0 0 0
> > >   1: 0 0 0 0 0
> > 0 0 9   524
> > >   12500: 0 0 9 0 0
> > 0 0 3  2544
> > >   2: 0 0 011 0
> > 0 046  3304
> > >   25000: 1 0 0 033
> > 0 0 0  7496
> > >   4: 0 0 0 016
> > 19 0 0  2024
> > >   5: 1 0 0 1 8
> > 1535 0  4032
> > > Total transition : 208
> > >
> > > Cheers,
> > > Biju
> > >


[PATCH v3 3/5] arm64: dts: allwinner: h6: Add GPU OPP table

2022-09-06 Thread Clément Péron
Add an Operating Performance Points table for the GPU to
enable Dynamic Voltage & Frequency Scaling on the H6.

The voltage range is set with minival voltage set to the target
and the maximal voltage set to 1.2V. This allow DVFS framework to
work properly on board with fixed regulator.

Signed-off-by: Clément Péron 
---
 .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 +++
 1 file changed, 87 insertions(+)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
new file mode 100644
index ..b48049c4fc85
--- /dev/null
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi
@@ -0,0 +1,87 @@
+// SPDX-License-Identifier: (GPL-2.0+ OR MIT)
+// Copyright (C) 2022 Clément Péron 
+
+/ {
+   gpu_opp_table: opp-table-gpu {
+   compatible = "operating-points-v2";
+
+   opp-21600 {
+   opp-hz = /bits/ 64 <21600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp-26400 {
+   opp-hz = /bits/ 64 <26400>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp-31200 {
+   opp-hz = /bits/ 64 <31200>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp-33600 {
+   opp-hz = /bits/ 64 <33600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp-36000 {
+   opp-hz = /bits/ 64 <36000>;
+   opp-microvolt = <82 82 120>;
+   };
+
+   opp-38400 {
+   opp-hz = /bits/ 64 <38400>;
+   opp-microvolt = <83 83 120>;
+   };
+
+   opp-40800 {
+   opp-hz = /bits/ 64 <40800>;
+   opp-microvolt = <84 84 120>;
+   };
+
+   opp-42000 {
+   opp-hz = /bits/ 64 <42000>;
+   opp-microvolt = <85 85 120>;
+   };
+
+   opp-43200 {
+   opp-hz = /bits/ 64 <43200>;
+   opp-microvolt = <86 86 120>;
+   };
+
+   opp-45600 {
+   opp-hz = /bits/ 64 <45600>;
+   opp-microvolt = <87 87 120>;
+   };
+
+   opp-50400 {
+   opp-hz = /bits/ 64 <50400>;
+   opp-microvolt = <89 89 120>;
+   };
+
+   opp-54000 {
+   opp-hz = /bits/ 64 <54000>;
+   opp-microvolt = <91 91 120>;
+   };
+
+   opp-57600 {
+   opp-hz = /bits/ 64 <57600>;
+   opp-microvolt = <93 93 120>;
+   };
+
+   opp-62400 {
+   opp-hz = /bits/ 64 <62400>;
+   opp-microvolt = <95 95 120>;
+   };
+
+   opp-75600 {
+   opp-hz = /bits/ 64 <75600>;
+   opp-microvolt = <104 104 120>;
+   };
+   };
+};
+
+ {
+   operating-points-v2 = <_opp_table>;
+};
-- 
2.34.1



[PATCH v3 5/5] arm64: dts: allwinner: beelink-gs1: Enable GPU OPP

2022-09-06 Thread Clément Péron
Enable GPU OPP table for Beelink GS1.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
index 6249e9e02928..9ec49ac2f6fd 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
@@ -5,6 +5,7 @@
 
 #include "sun50i-h6.dtsi"
 #include "sun50i-h6-cpu-opp.dtsi"
+#include "sun50i-h6-gpu-opp.dtsi"
 
 #include 
 
-- 
2.34.1



[PATCH v3 2/5] arm64: dts: allwinner: h6: Add cooling map for GPU

2022-09-06 Thread Clément Péron
Add a simple cooling map for the GPU.

This cooling map come from the vendor kernel 4.9 with a
2°C hysteresis added.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 51 +++-
 1 file changed, 49 insertions(+), 2 deletions(-)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 5a28303d3d4c..1259ab0c3956 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -186,6 +186,7 @@ gpu: gpu@180 {
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   #cooling-cells = <2>;
status = "disabled";
};
 
@@ -1072,9 +1073,55 @@ map0 {
};
 
gpu-thermal {
-   polling-delay-passive = <0>;
-   polling-delay = <0>;
+   polling-delay-passive = <1000>;
+   polling-delay = <2000>;
thermal-sensors = < 1>;
+
+   trips {
+   gpu_alert0: gpu-alert-0 {
+   temperature = <95000>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu_alert1: gpu-alert-1 {
+   temperature = <10>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu_alert2: gpu-alert-2 {
+   temperature = <105000>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu-crit {
+   temperature = <115000>;
+   hysteresis = <0>;
+   type = "critical";
+   };
+   };
+
+   cooling-maps {
+   // Fordid the GPU to go over 756MHz
+   map0 {
+   trip = <_alert0>;
+   cooling-device = < 1 
THERMAL_NO_LIMIT>;
+   };
+
+   // Fordid the GPU to go over 624MHz
+   map1 {
+   trip = <_alert1>;
+   cooling-device = < 2 
THERMAL_NO_LIMIT>;
+   };
+
+   // Fordid the GPU to go over 576MHz
+   map2 {
+   trip = <_alert2>;
+   cooling-device = < 3 
THERMAL_NO_LIMIT>;
+   };
+   };
};
};
 };
-- 
2.34.1



Re: [PATCH v3 4/5] drm/panfrost: devfreq: set opp to the recommended one to configure and enable regulator

2022-09-06 Thread Clément Péron
Hi,

On Mon, 5 Sept 2022 at 20:17, Biju Das  wrote:
>
> Hi,
>
> Thanks for the patch.
>
> > Subject: [PATCH v3 4/5] drm/panfrost: devfreq: set opp to the recommended
> > one to configure and enable regulator
> >
> > devm_pm_opp_set_regulators() doesn't enable regulator, which make
> > regulator framework switching it off during regulator_late_cleanup().
>
> In that case, why not regulator_get()for
> Dynamic regulator(non fixed regulator)??

Sorry I don't understand, what do you mean?

>
> >
> > Call dev_pm_opp_set_opp() with the recommend OPP in
> > panfrost_devfreq_init() to enable the regulator and avoid any switch off
> > by regulator_late_cleanup().
> >
> > Suggested-by: Viresh Kumar 
> > Signed-off-by: Clément Péron 
> > ---
> >  drivers/gpu/drm/panfrost/panfrost_devfreq.c | 8 
> >  1 file changed, 8 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > index 5110cd9b2425..67b242407156 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > @@ -131,6 +131,14 @@ int panfrost_devfreq_init(struct panfrost_device
> > *pfdev)
> >   return PTR_ERR(opp);
> >
> >   panfrost_devfreq_profile.initial_freq = cur_freq;
> > +
> > + /* Setup and enable regulator */
> > + ret = dev_pm_opp_set_opp(dev, opp);
> > + if (ret) {
> > + DRM_DEV_ERROR(dev, "Couldn't set recommended OPP\n");
> > + return ret;
> > + }
>
>
> FYI,
> On RZ/G2L mali gpu, we have fixed regulator and
> I was able to do GPU OPP transition without any issues previously.

rzg2l-smarc-som.dtsi uses regulator reg_1p1v;
which is marked as regulator-always-on; that's why
regulator_late_cleanup() doesn't switch it off.

Regards,
Clement

>
> root@smarc-rzg2l:~# cat /sys/class/devfreq/1184.gpu/trans_stat
>  From  :   To
>:  5000  6250 1 12500 2 25000 
> 4 5   time(ms)
> *  5000: 0 0 0 0 0 0  
>0 1   144
>6250: 0 0 0 0 0 0  
>0 0 0
>   1: 0 0 0 0 0 0  
>0 9   524
>   12500: 0 0 9 0 0 0  
>0 3  2544
>   2: 0 0 011 0 0  
>046  3304
>   25000: 1 0 0 033 0  
>0 0  7496
>   4: 0 0 0 01619  
>0 0  2024
>   5: 1 0 0 1 815  
>   35 0  4032
> Total transition : 208
>
> Cheers,
> Biju
>


[PATCH v3 1/5] arm64: defconfig: Enable devfreq cooling device

2022-09-06 Thread Clément Péron
Devfreq cooling device framework is used in Panfrost
to throttle GPU in order to regulate its temperature.

Enable this driver for ARM64 SoC.

Signed-off-by: Clément Péron 
Acked-by: Jernej Skrabec 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 91e58cf59c99..e557ccac8d9c 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -582,6 +582,7 @@ CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_INA3221=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
 CONFIG_IMX_SC_THERMAL=m
 CONFIG_IMX8MM_THERMAL=m
-- 
2.34.1



[PATCH v3 0/5] Allwinner H6 GPU devfreq

2022-09-06 Thread Clément Péron
Hi,

This is a refresh of previous patches sent to enable GPU Devfreq on H6
Beelink GS1 but that wasn't stable at that time[0].

With the recent fix on GPU PLL from Roman Stratiienko I have retested
and everything seems stable and works as expected[1].

Regards,
Clement

0: 
https://lore.kernel.org/lkml/cajiucce58gaxf_qg2cnmwvoguqyu__ekb3mdx1fe_+47htg...@mail.gmail.com/
1: https://lore.kernel.org/linux-arm-kernel/2562485.k3LOHGUjKi@kista/T/

Changes since v2:
 - Fixes device-tree warnings
 - Add panfrost fix to enable regulator
 - Remove always-on regulator from device-tree
 - Update cooling map from vendor kernel

Clément Péron (5):
  arm64: defconfig: Enable devfreq cooling device
  arm64: dts: allwinner: h6: Add cooling map for GPU
  arm64: dts: allwinner: h6: Add GPU OPP table
  drm/panfrost: devfreq: set opp to the recommended one to configure and
enable regulator
  arm64: dts: allwinner: beelink-gs1: Enable GPU OPP

 .../dts/allwinner/sun50i-h6-beelink-gs1.dts   |  1 +
 .../boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi | 87 +++
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 51 ++-
 arch/arm64/configs/defconfig  |  1 +
 drivers/gpu/drm/panfrost/panfrost_devfreq.c   |  8 ++
 5 files changed, 146 insertions(+), 2 deletions(-)
 create mode 100644 arch/arm64/boot/dts/allwinner/sun50i-h6-gpu-opp.dtsi

-- 
2.34.1



[PATCH v3 4/5] drm/panfrost: devfreq: set opp to the recommended one to configure and enable regulator

2022-09-06 Thread Clément Péron
devm_pm_opp_set_regulators() doesn't enable regulator, which make
regulator framework switching it off during regulator_late_cleanup().

Call dev_pm_opp_set_opp() with the recommend OPP in
panfrost_devfreq_init() to enable the regulator and avoid any switch off
by regulator_late_cleanup().

Suggested-by: Viresh Kumar 
Signed-off-by: Clément Péron 
---
 drivers/gpu/drm/panfrost/panfrost_devfreq.c | 8 
 1 file changed, 8 insertions(+)

diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c 
b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index 5110cd9b2425..67b242407156 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -131,6 +131,14 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
return PTR_ERR(opp);
 
panfrost_devfreq_profile.initial_freq = cur_freq;
+
+   /* Setup and enable regulator */
+   ret = dev_pm_opp_set_opp(dev, opp);
+   if (ret) {
+   DRM_DEV_ERROR(dev, "Couldn't set recommended OPP\n");
+   return ret;
+   }
+
dev_pm_opp_put(opp);
 
/*
-- 
2.34.1



Re: devfreq and panfrost on Allwinner H6

2020-11-22 Thread Clément Péron
HI Tomeu,

On Wed, 7 Oct 2020 at 19:49, Clément Péron  wrote:
>
> Hi Tomeu,
>
> On Wed, 7 Oct 2020 at 10:58, Tomeu Vizoso  wrote:
> >
> > Hi Clément,
> >
> > Have just noticed that my Pine H64 board hangs when I try to set the
> > performance governor for the GPU devfreq.
> >
> > Is this a known bug?
> Yes it is.
>
> I try to summarize everything in this message:
> https://lkml.org/lkml/2020/8/3/153

Finally got it working with Jernej's help by setting a fixed frequency
to the GPU PLL.

https://github.com/clementperon/linux/commits/h6_gpu_devfreq

# glmark2-es2-drm --off-screen
===
glmark2 2020.04
===
OpenGL Information
GL_VENDOR: Panfrost
GL_RENDERER:   Mali T720 (Panfrost)
GL_VERSION:OpenGL ES 3.0 Mesa 20.2.2
===
[build] use-vbo=false: FPS: 182 FrameTime: 5.495 ms
[build] use-vbo=true: FPS: 528 FrameTime: 1.894 ms
[texture] texture-filter=nearest: FPS: 604 FrameTime: 1.656 ms
[texture] texture-filter=linear: FPS: 599 FrameTime: 1.669 ms
[texture] texture-filter=mipmap: FPS: 581 FrameTime: 1.721 ms
[shading] shading=gouraud: FPS: 418 FrameTime: 2.392 ms
[shading] shading=blinn-phong-inf: FPS: 386 FrameTime: 2.591 ms
[shading] shading=phong: FPS: 325 FrameTime: 3.077 ms
[shading] shading=cel: FPS: 308 FrameTime: 3.247 ms
[bump] bump-render=high-poly: FPS: 214 FrameTime: 4.673 ms
[bump] bump-render=normals: FPS: 518 FrameTime: 1.931 ms
[bump] bump-render=height: FPS: 501 FrameTime: 1.996 ms
[effect2d] kernel=0,1,0;1,-4,1;0,1,0;: FPS: 295 FrameTime: 3.390 ms
[effect2d] kernel=1,1,1,1,1;1,1,1,1,1;1,1,1,1,1;: FPS: 82 FrameTime: 12.195 ms
[pulsar] light=false:quads=5:texture=false: FPS: 507 FrameTime: 1.972 ms
[desktop] blur-radius=5:effect=blur:passes=1:separable=true:windows=4:
FPS: 46 FrameTime: 21.739 ms
[desktop] effect=shadow:windows=4: FPS: 172 FrameTime: 5.814 ms
[buffer] 
columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=map:
FPS: 34 FrameTime: 29.412 ms
[buffer] 
columns=200:interleave=false:update-dispersion=0.9:update-fraction=0.5:update-method=subdata:
FPS: 33 FrameTime: 30.303 ms
[buffer] 
columns=200:interleave=true:update-dispersion=0.9:update-fraction=0.5:update-method=map:
FPS: 40 FrameTime: 25.000 ms
[ideas] speed=duration: FPS: 66 FrameTime: 15.152 ms
[jellyfish] : FPS: 158 FrameTime: 6.329 ms
[terrain] : FPS: 12 FrameTime: 83.333 ms
[shadow] : FPS: 211 FrameTime: 4.739 ms
[refract] : FPS: 45 FrameTime: 22.222 ms
[conditionals] fragment-steps=0:vertex-steps=0: FPS: 654 FrameTime: 1.529 ms
[conditionals] fragment-steps=5:vertex-steps=0: FPS: 296 FrameTime: 3.378 ms
[conditionals] fragment-steps=0:vertex-steps=5: FPS: 645 FrameTime: 1.550 ms
[function] fragment-complexity=low:fragment-steps=5: FPS: 468
FrameTime: 2.137 ms
[function] fragment-complexity=medium:fragment-steps=5: FPS: 289
FrameTime: 3.460 ms
[loop] fragment-loop=false:fragment-steps=5:vertex-steps=5: FPS: 459
FrameTime: 2.179 ms
[loop] fragment-steps=5:fragment-uniform=false:vertex-steps=5: FPS:
460 FrameTime: 2.174 ms
[loop] fragment-steps=5:fragment-uniform=true:vertex-steps=5: FPS: 218
FrameTime: 4.587 ms
===
  glmark2 Score: 313
===

Regards,
Clement

>
> Clement
>
> >
> > Thanks,
> >
> > Tomeu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: devfreq and panfrost on Allwinner H6

2020-10-08 Thread Clément Péron
Hi Tomeu,

On Wed, 7 Oct 2020 at 10:58, Tomeu Vizoso  wrote:
>
> Hi Clément,
>
> Have just noticed that my Pine H64 board hangs when I try to set the
> performance governor for the GPU devfreq.
>
> Is this a known bug?
Yes it is.

I try to summarize everything in this message:
https://lkml.org/lkml/2020/8/3/153

Clement

>
> Thanks,
>
> Tomeu
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 13/14] [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table

2020-08-29 Thread Clément Péron
Hi Maxime,

On Tue, 25 Aug 2020 at 15:35, Maxime Ripard  wrote:
>
> Hi Clement,
>
> On Mon, Aug 03, 2020 at 09:54:05AM +0200, Clément Péron wrote:
> > Hi Maxime and All,
> >
> > On Sat, 4 Jul 2020 at 16:56, Clément Péron  wrote:
> > >
> > > Hi Maxime,
> > >
> > > On Sat, 4 Jul 2020 at 14:13, Maxime Ripard  wrote:
> > > >
> > > > Hi,
> > > >
> > > > On Sat, Jul 04, 2020 at 12:25:34PM +0200, Clément Péron wrote:
> > > > > Add an Operating Performance Points table for the GPU to
> > > > > enable Dynamic Voltage & Frequency Scaling on the H6.
> > > > >
> > > > > The voltage range is set with minival voltage set to the target
> > > > > and the maximal voltage set to 1.2V. This allow DVFS framework to
> > > > > work properly on board with fixed regulator.
> > > > >
> > > > > Signed-off-by: Clément Péron 
> > > >
> > > > That patch seems reasonable, why shouldn't we merge it?
> > >
> > > I didn't test it a lot and last time I did, some frequencies looked 
> > > unstable.
> > > https://lore.kernel.org/patchwork/cover/1239739/
> > >
> > > This series adds regulator support to Panfrost devfreq, I will send a
> > > new one if DVFS on the H6 GPU is stable.
> > >
> > > I got this running glmark2 last time
> > > # glmark2-es2-drm
> > > ===
> > > glmark2 2017.07
> > > ===
> > > OpenGL Information
> > > GL_VENDOR: Panfrost
> > > GL_RENDERER:   Mali T720 (Panfrost)
> > > GL_VERSION:OpenGL ES 2.0 Mesa 20.0.5
> > > ===
> > >
> > > [   93.550063] panfrost 180.gpu: GPU Fault 0x0088 (UNKNOWN) at
> > > 0x80117100
> > > [   94.045401] panfrost 180.gpu: gpu sched timeout, js=0,
> > > config=0x3700, status=0x8, head=0x21d6c00, tail=0x21d6c00,
> > > sched_job=e3c2132f
> > >
> > > [  328.871070] panfrost 180.gpu: Unhandled Page fault in AS0 at VA
> > > 0x
> > > [  328.871070] Reason: TODO
> > > [  328.871070] raw fault status: 0xAA0003C2
> > > [  328.871070] decoded fault status: SLAVE FAULT
> > > [  328.871070] exception type 0xC2: TRANSLATION_FAULT_LEVEL2
> > > [  328.871070] access type 0x3: WRITE
> > > [  328.871070] source id 0xAA00
> > > [  329.373327] panfrost 180.gpu: gpu sched timeout, js=1,
> > > config=0x3700, status=0x8, head=0xa1a4900, tail=0xa1a4900,
> > > sched_job=7ac31097
> > > [  329.386527] panfrost 180.gpu: js fault, js=0,
> > > status=DATA_INVALID_FAULT, head=0xa1a4c00, tail=0xa1a4c00
> > > [  329.396293] panfrost 180.gpu: gpu sched timeout, js=0,
> > > config=0x3700, status=0x58, head=0xa1a4c00, tail=0xa1a4c00,
> > > sched_job=04c90381
> > > [  329.411521] panfrost 180.gpu: Unhandled Page fault in AS0 at VA
> > > 0x
> > > [  329.411521] Reason: TODO
> > > [  329.411521] raw fault status: 0xAA0003C2
> > > [  329.411521] decoded fault status: SLAVE FAULT
> > > [  329.411521] exception type 0xC2: TRANSLATION_FAULT_LEVEL2
> > > [  329.411521] access type 0x3: WRITE
> > > [  329.411521] source id 0xAA00
> >
> > Just to keep a track of this issue.
> >
> > Piotr Oniszczuk give more test and seems to be software related:
> > https://www.spinics.net/lists/dri-devel/msg264279.html
> >
> > Ondrej gave a great explanation about a possible origin of this issue:
> > https://freenode.irclog.whitequark.org/linux-sunxi/2020-07-11
> >
> > 20:12  looks like gpu pll on H6 is NKMP clock, and those are
> > implemented in such a way in mainline that they are prone to
> > overshooting the frequency during output divider reduction
> > 20:13  so disabling P divider may help
> > 20:13  or fixing the dividers
> > 20:14  and just allowing N to change
> > 20:22  hmm, I haven't looked at this for quite some time, but H6
> > BSP way of setting PLL factors actually makes the most sense out of
> > everything I've seen/tested so far
> > 20:23  it waits for lock not after setting NK factors, but after
> > reducing the M factor (pre-divider)
> > 20:24  I might as well re-run my CPU PLL tester with this
> > algorithm, to see if it fixes the lockups

Re: [PATCH v5 00/14] Add regulator devfreq support to Panfrost

2020-08-10 Thread Clément Péron
On Fri, 7 Aug 2020 at 18:28, Clément Péron  wrote:
>
> Hi Rob,
>
> On Fri, 7 Aug 2020 at 18:13, Rob Herring  wrote:
> >
> > On Fri, Jul 10, 2020 at 3:54 AM Clément Péron  wrote:
> > >
> > > Hi,
> > >
> > > This serie cleans and adds regulator support to Panfrost devfreq.
> > > This is mostly based on comment for the freshly introduced lima
> > > devfreq.
> > >
> > > We need to add regulator support because on Allwinner the GPU OPP
> > > table defines both frequencies and voltages.
> > >
> > > First patches [01-07] should not change the actual behavior
> > > and introduce a proper panfrost_devfreq struct.
> > >
> > > Regards,
> > > Clément
> > >
> > > Changes since v4:
> > >  - Fix missed a pfdev to >devfreq during rebase
> > >
> > > Changes since v3:
> > >  - Collect Steven Price reviewed-by tags
> > >  - Rebase on next/master (next-20200709)
> > >
> > > Changes since v2:
> > >  - Collect Alyssa Rosenzweig reviewed-by tags
> > >  - Fix opp_set_regulator before adding opp_table (introduce in v2)
> > >  - Call err_fini in case opp_add_table failed
> > >
> > > Changes since v1:
> > >  - Collect Steven Price reviewed-by tags
> > >  - Fix spinlock comment
> > >  - Drop OPP clock-name patch
> > >  - Drop device_property_test patch
> > >  - Add rename error labels patch
> > >
> > > Clément Péron (14):
> > >   drm/panfrost: avoid static declaration
> > >   drm/panfrost: clean headers in devfreq
> > >   drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle
> > >   drm/panfrost: introduce panfrost_devfreq struct
> > >   drm/panfrost: use spinlock instead of atomic
> > >   drm/panfrost: properly handle error in probe
> > >   drm/panfrost: rename error labels in device_init
> > >   drm/panfrost: move devfreq_init()/fini() in device
> > >   drm/panfrost: dynamically alloc regulators
> > >   drm/panfrost: add regulators to devfreq
> > >   arm64: defconfig: Enable devfreq cooling device
> > >   arm64: dts: allwinner: h6: Add cooling map for GPU
> > >   [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table
> > >   [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always
> >
> > Patches 1-10 applied to drm-misc.
>
> This serie has been superseded by v5.
>
> Could you apply the v5 instead.

Oups forget my email

I got an issue with my gmail...

Thanks

>
> Thanks
> Clément
>
> >
> > Rob
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v5 00/14] Add regulator devfreq support to Panfrost

2020-08-10 Thread Clément Péron
Hi Rob,

On Fri, 7 Aug 2020 at 18:13, Rob Herring  wrote:
>
> On Fri, Jul 10, 2020 at 3:54 AM Clément Péron  wrote:
> >
> > Hi,
> >
> > This serie cleans and adds regulator support to Panfrost devfreq.
> > This is mostly based on comment for the freshly introduced lima
> > devfreq.
> >
> > We need to add regulator support because on Allwinner the GPU OPP
> > table defines both frequencies and voltages.
> >
> > First patches [01-07] should not change the actual behavior
> > and introduce a proper panfrost_devfreq struct.
> >
> > Regards,
> > Clément
> >
> > Changes since v4:
> >  - Fix missed a pfdev to >devfreq during rebase
> >
> > Changes since v3:
> >  - Collect Steven Price reviewed-by tags
> >  - Rebase on next/master (next-20200709)
> >
> > Changes since v2:
> >  - Collect Alyssa Rosenzweig reviewed-by tags
> >  - Fix opp_set_regulator before adding opp_table (introduce in v2)
> >  - Call err_fini in case opp_add_table failed
> >
> > Changes since v1:
> >  - Collect Steven Price reviewed-by tags
> >  - Fix spinlock comment
> >  - Drop OPP clock-name patch
> >  - Drop device_property_test patch
> >  - Add rename error labels patch
> >
> > Clément Péron (14):
> >   drm/panfrost: avoid static declaration
> >   drm/panfrost: clean headers in devfreq
> >   drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle
> >   drm/panfrost: introduce panfrost_devfreq struct
> >   drm/panfrost: use spinlock instead of atomic
> >   drm/panfrost: properly handle error in probe
> >   drm/panfrost: rename error labels in device_init
> >   drm/panfrost: move devfreq_init()/fini() in device
> >   drm/panfrost: dynamically alloc regulators
> >   drm/panfrost: add regulators to devfreq
> >   arm64: defconfig: Enable devfreq cooling device
> >   arm64: dts: allwinner: h6: Add cooling map for GPU
> >   [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table
> >   [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always
>
> Patches 1-10 applied to drm-misc.

This serie has been superseded by v5.

Could you apply the v5 instead.

Thanks
Clément

>
> Rob
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 13/14] [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table

2020-08-03 Thread Clément Péron
Hi Maxime and All,

On Sat, 4 Jul 2020 at 16:56, Clément Péron  wrote:
>
> Hi Maxime,
>
> On Sat, 4 Jul 2020 at 14:13, Maxime Ripard  wrote:
> >
> > Hi,
> >
> > On Sat, Jul 04, 2020 at 12:25:34PM +0200, Clément Péron wrote:
> > > Add an Operating Performance Points table for the GPU to
> > > enable Dynamic Voltage & Frequency Scaling on the H6.
> > >
> > > The voltage range is set with minival voltage set to the target
> > > and the maximal voltage set to 1.2V. This allow DVFS framework to
> > > work properly on board with fixed regulator.
> > >
> > > Signed-off-by: Clément Péron 
> >
> > That patch seems reasonable, why shouldn't we merge it?
>
> I didn't test it a lot and last time I did, some frequencies looked unstable.
> https://lore.kernel.org/patchwork/cover/1239739/
>
> This series adds regulator support to Panfrost devfreq, I will send a
> new one if DVFS on the H6 GPU is stable.
>
> I got this running glmark2 last time
> # glmark2-es2-drm
> ===
> glmark2 2017.07
> ===
> OpenGL Information
> GL_VENDOR: Panfrost
> GL_RENDERER:   Mali T720 (Panfrost)
> GL_VERSION:OpenGL ES 2.0 Mesa 20.0.5
> ===
>
> [   93.550063] panfrost 180.gpu: GPU Fault 0x0088 (UNKNOWN) at
> 0x80117100
> [   94.045401] panfrost 180.gpu: gpu sched timeout, js=0,
> config=0x3700, status=0x8, head=0x21d6c00, tail=0x21d6c00,
> sched_job=e3c2132f
>
> [  328.871070] panfrost 180.gpu: Unhandled Page fault in AS0 at VA
> 0x
> [  328.871070] Reason: TODO
> [  328.871070] raw fault status: 0xAA0003C2
> [  328.871070] decoded fault status: SLAVE FAULT
> [  328.871070] exception type 0xC2: TRANSLATION_FAULT_LEVEL2
> [  328.871070] access type 0x3: WRITE
> [  328.871070] source id 0xAA00
> [  329.373327] panfrost 180.gpu: gpu sched timeout, js=1,
> config=0x3700, status=0x8, head=0xa1a4900, tail=0xa1a4900,
> sched_job=7ac31097
> [  329.386527] panfrost 180.gpu: js fault, js=0,
> status=DATA_INVALID_FAULT, head=0xa1a4c00, tail=0xa1a4c00
> [  329.396293] panfrost 180.gpu: gpu sched timeout, js=0,
> config=0x3700, status=0x58, head=0xa1a4c00, tail=0xa1a4c00,
> sched_job=04c90381
> [  329.411521] panfrost 180.gpu: Unhandled Page fault in AS0 at VA
> 0x
> [  329.411521] Reason: TODO
> [  329.411521] raw fault status: 0xAA0003C2
> [  329.411521] decoded fault status: SLAVE FAULT
> [  329.411521] exception type 0xC2: TRANSLATION_FAULT_LEVEL2
> [  329.411521] access type 0x3: WRITE
> [  329.411521] source id 0xAA00

Just to keep a track of this issue.

Piotr Oniszczuk give more test and seems to be software related:
https://www.spinics.net/lists/dri-devel/msg264279.html

Ondrej gave a great explanation about a possible origin of this issue:
https://freenode.irclog.whitequark.org/linux-sunxi/2020-07-11

20:12  looks like gpu pll on H6 is NKMP clock, and those are
implemented in such a way in mainline that they are prone to
overshooting the frequency during output divider reduction
20:13  so disabling P divider may help
20:13  or fixing the dividers
20:14  and just allowing N to change
20:22  hmm, I haven't looked at this for quite some time, but H6
BSP way of setting PLL factors actually makes the most sense out of
everything I've seen/tested so far
20:23  it waits for lock not after setting NK factors, but after
reducing the M factor (pre-divider)
20:24  I might as well re-run my CPU PLL tester with this
algorithm, to see if it fixes the lockups
20:26  it makes sense to wait for PLL to stabilize "after"
changing all the factors that actually affect the VCO, and not just
some of them
20:27  warpme_: ^
20:28  it may be the same thing that plagues the CPU PLL rate
changes at runtime

Regards,
Clement

>
> Regards,
> Clement
>
> >
> > > ---
> > >  arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 80 
> > >  1 file changed, 80 insertions(+)
> > >
> > > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
> > > b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> > > index 8f514a2169aa..a69f9e09a829 100644
> > > --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> > > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> > > @@ -174,6 +174,7 @@ gpu: gpu@180 {
> > >   clocks = < CLK_GPU>, < CLK_BUS_GPU>;
> > >   clock-names = "core", "bus";
> > >   resets = 

[PATCH v5 00/14] Add regulator devfreq support to Panfrost

2020-07-14 Thread Clément Péron
Hi,

This serie cleans and adds regulator support to Panfrost devfreq.
This is mostly based on comment for the freshly introduced lima
devfreq.

We need to add regulator support because on Allwinner the GPU OPP
table defines both frequencies and voltages.

First patches [01-07] should not change the actual behavior
and introduce a proper panfrost_devfreq struct.

Regards,
Clément

Changes since v4:
 - Fix missed a pfdev to >devfreq during rebase

Changes since v3:
 - Collect Steven Price reviewed-by tags
 - Rebase on next/master (next-20200709)

Changes since v2:
 - Collect Alyssa Rosenzweig reviewed-by tags
 - Fix opp_set_regulator before adding opp_table (introduce in v2)
 - Call err_fini in case opp_add_table failed

Changes since v1:
 - Collect Steven Price reviewed-by tags
 - Fix spinlock comment
 - Drop OPP clock-name patch
 - Drop device_property_test patch
 - Add rename error labels patch

Clément Péron (14):
  drm/panfrost: avoid static declaration
  drm/panfrost: clean headers in devfreq
  drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle
  drm/panfrost: introduce panfrost_devfreq struct
  drm/panfrost: use spinlock instead of atomic
  drm/panfrost: properly handle error in probe
  drm/panfrost: rename error labels in device_init
  drm/panfrost: move devfreq_init()/fini() in device
  drm/panfrost: dynamically alloc regulators
  drm/panfrost: add regulators to devfreq
  arm64: defconfig: Enable devfreq cooling device
  arm64: dts: allwinner: h6: Add cooling map for GPU
  [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table
  [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always

 .../dts/allwinner/sun50i-h6-beelink-gs1.dts   |   1 +
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 102 ++
 arch/arm64/configs/defconfig  |   1 +
 drivers/gpu/drm/panfrost/panfrost_devfreq.c   | 175 --
 drivers/gpu/drm/panfrost/panfrost_devfreq.h   |  30 ++-
 drivers/gpu/drm/panfrost/panfrost_device.c|  61 +++---
 drivers/gpu/drm/panfrost/panfrost_device.h|  14 +-
 drivers/gpu/drm/panfrost/panfrost_drv.c   |  15 +-
 drivers/gpu/drm/panfrost/panfrost_job.c   |  10 +-
 9 files changed, 296 insertions(+), 113 deletions(-)

-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 09/14] drm/panfrost: dynamically alloc regulators

2020-07-14 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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];
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 04/14] drm/panfrost: introduce panfrost_devfreq struct

2020-07-14 Thread Clément Péron
Introduce a proper panfrost_devfreq to deal with devfreq variables.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>devfreq.busy_count) > 0)
-   pfdev->devfreq.busy_time += ktime_sub(now, last);
+   if (atomic_read(>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 = >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 = >pdev->dev;
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
+   struct panfrost_devfreq *pfdevfreq = >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;

Re: [PATCH v3 13/14] [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table

2020-07-14 Thread Clément Péron
Hi,

On Fri, 10 Jul 2020 at 15:45, Piotr Oniszczuk  wrote:
>
>
>
> > Wiadomość napisana przez Clément Péron  w dniu 
> > 09.07.2020, o godz. 16:03:
> >
> > Add an Operating Performance Points table for the GPU to
> > enable Dynamic Voltage & Frequency Scaling on the H6.
> >
> > The voltage range is set with minival voltage set to the target
> > and the maximal voltage set to 1.2V. This allow DVFS framework to
> > work properly on board with fixed regulator.
> >
> > Signed-off-by: Clément Péron 
> > ---
> > arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 80 
> > 1 file changed, 80 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
> > b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> > index 8f514a2169aa..a69f9e09a829 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> > @@ -174,6 +174,7 @@ gpu: gpu@180 {
> >   clocks = < CLK_GPU>, < CLK_BUS_GPU>;
> >   clock-names = "core", "bus";
> >   resets = < RST_BUS_GPU>;
> > + operating-points-v2 = <_opp_table>;
> >   #cooling-cells = <2>;
> >   status = "disabled";
> >   };
> > @@ -1036,4 +1037,83 @@ map0 {
> >   };
> >   };
> >   };
> > +
> > + gpu_opp_table: gpu-opp-table {
> > + compatible = "operating-points-v2";
> > +
> > + opp@21600 {
> > + opp-hz = /bits/ 64 <21600>;
> > + opp-microvolt = <81 81 120>;
> > + };
> > +
> > + opp@26400 {
> > + opp-hz = /bits/ 64 <26400>;
> > + opp-microvolt = <81 81 120>;
> > + };
> > +
> > + opp@31200 {
> > + opp-hz = /bits/ 64 <31200>;
> > + opp-microvolt = <81 81 120>;
> > + };
> > +
> > + opp@33600 {
> > + opp-hz = /bits/ 64 <33600>;
> > + opp-microvolt = <81 81 120>;
> > + };
> > +
> > + opp@36000 {
> > + opp-hz = /bits/ 64 <36000>;
> > + opp-microvolt = <82 82 120>;
> > + };
> > +
> > + opp@38400 {
> > + opp-hz = /bits/ 64 <38400>;
> > + opp-microvolt = <83 83 120>;
> > + };
> > +
> > + opp@40800 {
> > + opp-hz = /bits/ 64 <40800>;
> > + opp-microvolt = <84 84 120>;
> > + };
> > +
> > + opp@42000 {
> > + opp-hz = /bits/ 64 <42000>;
> > + opp-microvolt = <85 85 120>;
> > + };
> > +
> > + opp@43200 {
> > + opp-hz = /bits/ 64 <43200>;
> > + opp-microvolt = <86 86 120>;
> > + };
> > +
> > + opp@45600 {
> > + opp-hz = /bits/ 64 <45600>;
> > + opp-microvolt = <87 87 120>;
> > + };
> > +
> > + opp@50400 {
> > + opp-hz = /bits/ 64 <50400>;
> > + opp-microvolt = <89 89 120>;
> > + };
> > +
> > + opp@54000 {
> > + opp-hz = /bits/ 64 <54000>;
> > + opp-microvolt = <91 91 120>;
> > + };
> > +
> > + opp@57600 {
> > + opp-hz = /bits/ 64 <57600>;
> > + opp-microvolt = <93 93 120>;
> > + };
> > +
> > + opp@62400 {
> > + opp-hz = /bits/ 64 <62400>;
> > + opp-microvolt = <95 95 120>;
> > + };
> > +
> > +  

[PATCH v4 03/14] drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle

2020-07-14 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 360146f6f3d9..4c13dbae68fb 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(>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(>queue[i].sched.hw_rq_count))
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 07/14] drm/panfrost: rename error labels in device_init

2020-07-14 Thread Clément Péron
Rename goto labels in device_init it will be easier to maintain.

Reviewed-by: Alyssa Rosenzweig 
Reviewed-by: Steven Price 
Signed-off-by: Clément Péron 
---
 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;
 }
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 05/14] drm/panfrost: use spinlock instead of atomic

2020-07-14 Thread Clément Péron
Convert busy_count to a simple int protected by spinlock.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>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 = >pfdevfreq;
+   unsigned long irqflags;
+
+   status->current_frequency = clk_get_rate(pfdev->clock);
+
+   spin_lock_irqsave(>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(>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(>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(>lock, irqflags);
+
panfrost_devfreq_update_utilization(pfdevfreq);
-   atomic_inc(>busy_count);
+
+   pfdevfreq->busy_count++;
+
+   spin_unlock_irqrestore(>lock, irqflags);
 }
 
 void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq)
 {
-   int count;
+   unsigned long irqflags;
+
+   if (!pfdevfreq->devfreq)
+   return;
+
+   spin_lock_irqsave(>lock, irqflags);
 
panfrost_devfreq_update_utilization(pfdevfreq);
-   count = atomic_dec_if_positive(>busy_count);
-   WARN_ON(count < 0);
+
+   WARN_ON(--pfdevfreq->busy_count < 0);
+
+   spin_unlock_irqrestore(>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 
 #include 
 
 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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 06/14] drm/panfrost: properly handle error in probe

2020-07-14 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>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, _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 = >pfdevfreq;
 
-   if (pfdevfreq->cooling)
+   if (pfdevfreq->cooling) {
devfreq_cooling_unregister(pfdevfreq->cooling);
-   dev_pm_opp_of_remove_table(>pdev->dev);
+   pfdevfreq->cooling = NULL;
+   }
+
+   if (pfdevfreq->opp_of_table_added) {
+   dev_pm_opp_of_remove_table(>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;
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 05/14] drm/panfrost: use spinlock instead of atomic

2020-07-14 Thread Clément Péron
Convert busy_count to a simple int protected by spinlock.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>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 = >pfdevfreq;
+   unsigned long irqflags;
+
+   status->current_frequency = clk_get_rate(pfdev->clock);
+
+   spin_lock_irqsave(>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(>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(>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(>lock, irqflags);
+
panfrost_devfreq_update_utilization(pfdevfreq);
-   atomic_inc(>busy_count);
+
+   pfdevfreq->busy_count++;
+
+   spin_unlock_irqrestore(>lock, irqflags);
 }
 
 void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq)
 {
-   int count;
+   unsigned long irqflags;
+
+   if (!pfdevfreq->devfreq)
+   return;
+
+   spin_lock_irqsave(>lock, irqflags);
 
panfrost_devfreq_update_utilization(pfdevfreq);
-   count = atomic_dec_if_positive(>busy_count);
-   WARN_ON(count < 0);
+
+   WARN_ON(--pfdevfreq->busy_count < 0);
+
+   spin_unlock_irqrestore(>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 
 #include 
 
 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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 10/14] drm/panfrost: add regulators to devfreq

2020-07-14 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 = >pdev->dev;
struct devfreq *devfreq;
+   struct opp_table *opp_table;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = >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(>lock);
@@ -153,6 +169,11 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev)
dev_pm_opp_of_remove_table(>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 
 
 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) {
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 09/14] drm/panfrost: dynamically alloc regulators

2020-07-14 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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];
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 02/14] drm/panfrost: clean headers in devfreq

2020-07-14 Thread Clément Péron
Don't include not required headers and sort them.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 
 #include 
 #include 
 #include 
 #include 
-#include 
-#include 
 
 #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)
 {
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 11/14] arm64: defconfig: Enable devfreq cooling device

2020-07-14 Thread Clément Péron
Devfreq cooling device framework is used in Panfrost
to throttle GPU in order to regulate its temperature.

Enable this driver for ARM64 SoC.

Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 89538d9e39e5..8a295bcb4dd3 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -504,6 +504,7 @@ CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_INA3221=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
 CONFIG_QORIQ_THERMAL=m
 CONFIG_SUN8I_THERMAL=y
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 08/14] drm/panfrost: move devfreq_init()/fini() in device

2020-07-14 Thread Clément Péron
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 
Reviewed-by: Steven Price 
Signed-off-by: Clément Péron 
---
 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 ada51df9a7a3..170d6dbab217 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -14,7 +14,6 @@
 #include 
 
 #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(>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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 14/14] [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always

2020-07-14 Thread Clément Péron
Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
index 3f7ceeb1a767..14257f7476b8 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
@@ -245,6 +245,7 @@ reg_dcdca: dcdca {
};
 
reg_dcdcc: dcdcc {
+   regulator-always-on;
regulator-enable-ramp-delay = <32000>;
regulator-min-microvolt = <81>;
regulator-max-microvolt = <108>;
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v4 04/14] drm/panfrost: introduce panfrost_devfreq struct

2020-07-14 Thread Clément Péron
Hi,

On Fri, 10 Jul 2020 at 11:25, Clément Péron  wrote:
>
> Introduce a proper panfrost_devfreq to deal with devfreq variables.
>
> Reviewed-by: Steven Price 
> Reviewed-by: Alyssa Rosenzweig 
> Signed-off-by: Clément Péron 
> ---
>  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 |  4 +-
>  4 files changed, 65 insertions(+), 46 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(>devfreq.busy_count) > 0)
> -   pfdev->devfreq.busy_time += ktime_sub(now, last);
> +   if (atomic_read(>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 = >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 = >pdev->dev;
> struct devfreq *devfreq;
> struct thermal_cooling_device *cooling;
> +   struct panfrost_devfreq *pfdevfreq = >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);
>

[PATCH v4 10/14] drm/panfrost: add regulators to devfreq

2020-07-14 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 = >pdev->dev;
struct devfreq *devfreq;
+   struct opp_table *opp_table;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = >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(>lock);
@@ -153,6 +169,11 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev)
dev_pm_opp_of_remove_table(>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 
 
 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) {
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 14/14] [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always

2020-07-14 Thread Clément Péron
Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
index 3f7ceeb1a767..14257f7476b8 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
@@ -245,6 +245,7 @@ reg_dcdca: dcdca {
};
 
reg_dcdcc: dcdcc {
+   regulator-always-on;
regulator-enable-ramp-delay = <32000>;
regulator-min-microvolt = <81>;
regulator-max-microvolt = <108>;
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 11/14] arm64: defconfig: Enable devfreq cooling device

2020-07-14 Thread Clément Péron
Devfreq cooling device framework is used in Panfrost
to throttle GPU in order to regulate its temperature.

Enable this driver for ARM64 SoC.

Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 89538d9e39e5..8a295bcb4dd3 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -504,6 +504,7 @@ CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_INA3221=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
 CONFIG_QORIQ_THERMAL=m
 CONFIG_SUN8I_THERMAL=y
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 12/14] arm64: dts: allwinner: h6: Add cooling map for GPU

2020-07-14 Thread Clément Péron
Add a simple cooling map for the GPU.

Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 22 
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 9ce78a7b117d..1c939c55aaea 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -175,6 +175,7 @@ gpu: gpu@180 {
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   #cooling-cells = <2>;
status = "disabled";
};
 
@@ -1013,6 +1014,27 @@ gpu-thermal {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = < 1>;
+
+   trips {
+   gpu_alert: gpu-alert {
+   temperature = <85000>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu-crit {
+   temperature = <10>;
+   hysteresis = <0>;
+   type = "critical";
+   };
+   };
+
+   cooling-maps {
+   map0 {
+   trip = <_alert>;
+   cooling-device = < THERMAL_NO_LIMIT 
THERMAL_NO_LIMIT>;
+   };
+   };
};
};
 };
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 08/14] drm/panfrost: move devfreq_init()/fini() in device

2020-07-14 Thread Clément Péron
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 
Reviewed-by: Steven Price 
Signed-off-by: Clément Péron 
---
 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 ada51df9a7a3..170d6dbab217 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -14,7 +14,6 @@
 #include 
 
 #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(>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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 12/14] arm64: dts: allwinner: h6: Add cooling map for GPU

2020-07-14 Thread Clément Péron
Add a simple cooling map for the GPU.

Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 22 
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 9ce78a7b117d..1c939c55aaea 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -175,6 +175,7 @@ gpu: gpu@180 {
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   #cooling-cells = <2>;
status = "disabled";
};
 
@@ -1013,6 +1014,27 @@ gpu-thermal {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = < 1>;
+
+   trips {
+   gpu_alert: gpu-alert {
+   temperature = <85000>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu-crit {
+   temperature = <10>;
+   hysteresis = <0>;
+   type = "critical";
+   };
+   };
+
+   cooling-maps {
+   map0 {
+   trip = <_alert>;
+   cooling-device = < THERMAL_NO_LIMIT 
THERMAL_NO_LIMIT>;
+   };
+   };
};
};
 };
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 07/14] drm/panfrost: rename error labels in device_init

2020-07-14 Thread Clément Péron
Rename goto labels in device_init it will be easier to maintain.

Reviewed-by: Alyssa Rosenzweig 
Reviewed-by: Steven Price 
Signed-off-by: Clément Péron 
---
 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;
 }
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 06/14] drm/panfrost: properly handle error in probe

2020-07-14 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>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, _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 = >pfdevfreq;
 
-   if (pfdevfreq->cooling)
+   if (pfdevfreq->cooling) {
devfreq_cooling_unregister(pfdevfreq->cooling);
-   dev_pm_opp_of_remove_table(>pdev->dev);
+   pfdevfreq->cooling = NULL;
+   }
+
+   if (pfdevfreq->opp_of_table_added) {
+   dev_pm_opp_of_remove_table(>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;
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 01/14] drm/panfrost: avoid static declaration

2020-07-14 Thread Clément Péron
This declaration can be avoided so change it.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>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(>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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 03/14] drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle

2020-07-14 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 360146f6f3d9..4c13dbae68fb 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(>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(>queue[i].sched.hw_rq_count))
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 13/14] [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table

2020-07-14 Thread Clément Péron
Add an Operating Performance Points table for the GPU to
enable Dynamic Voltage & Frequency Scaling on the H6.

The voltage range is set with minival voltage set to the target
and the maximal voltage set to 1.2V. This allow DVFS framework to
work properly on board with fixed regulator.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 80 
 1 file changed, 80 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 1c939c55aaea..16c3ad8abd9d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -175,6 +175,7 @@ gpu: gpu@180 {
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   operating-points-v2 = <_opp_table>;
#cooling-cells = <2>;
status = "disabled";
};
@@ -1037,4 +1038,83 @@ map0 {
};
};
};
+
+   gpu_opp_table: gpu-opp-table {
+   compatible = "operating-points-v2";
+
+   opp@21600 {
+   opp-hz = /bits/ 64 <21600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@26400 {
+   opp-hz = /bits/ 64 <26400>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@31200 {
+   opp-hz = /bits/ 64 <31200>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@33600 {
+   opp-hz = /bits/ 64 <33600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@36000 {
+   opp-hz = /bits/ 64 <36000>;
+   opp-microvolt = <82 82 120>;
+   };
+
+   opp@38400 {
+   opp-hz = /bits/ 64 <38400>;
+   opp-microvolt = <83 83 120>;
+   };
+
+   opp@40800 {
+   opp-hz = /bits/ 64 <40800>;
+   opp-microvolt = <84 84 120>;
+   };
+
+   opp@42000 {
+   opp-hz = /bits/ 64 <42000>;
+   opp-microvolt = <85 85 120>;
+   };
+
+   opp@43200 {
+   opp-hz = /bits/ 64 <43200>;
+   opp-microvolt = <86 86 120>;
+   };
+
+   opp@45600 {
+   opp-hz = /bits/ 64 <45600>;
+   opp-microvolt = <87 87 120>;
+   };
+
+   opp@50400 {
+   opp-hz = /bits/ 64 <50400>;
+   opp-microvolt = <89 89 120>;
+   };
+
+   opp@54000 {
+   opp-hz = /bits/ 64 <54000>;
+   opp-microvolt = <91 91 120>;
+   };
+
+   opp@57600 {
+   opp-hz = /bits/ 64 <57600>;
+   opp-microvolt = <93 93 120>;
+   };
+
+   opp@62400 {
+   opp-hz = /bits/ 64 <62400>;
+   opp-microvolt = <95 95 120>;
+   };
+
+   opp@75600 {
+   opp-hz = /bits/ 64 <75600>;
+   opp-microvolt = <104 104 120>;
+   };
+   };
 };
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 13/14] [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table

2020-07-14 Thread Clément Péron
Add an Operating Performance Points table for the GPU to
enable Dynamic Voltage & Frequency Scaling on the H6.

The voltage range is set with minival voltage set to the target
and the maximal voltage set to 1.2V. This allow DVFS framework to
work properly on board with fixed regulator.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 80 
 1 file changed, 80 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 1c939c55aaea..16c3ad8abd9d 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -175,6 +175,7 @@ gpu: gpu@180 {
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   operating-points-v2 = <_opp_table>;
#cooling-cells = <2>;
status = "disabled";
};
@@ -1037,4 +1038,83 @@ map0 {
};
};
};
+
+   gpu_opp_table: gpu-opp-table {
+   compatible = "operating-points-v2";
+
+   opp@21600 {
+   opp-hz = /bits/ 64 <21600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@26400 {
+   opp-hz = /bits/ 64 <26400>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@31200 {
+   opp-hz = /bits/ 64 <31200>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@33600 {
+   opp-hz = /bits/ 64 <33600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@36000 {
+   opp-hz = /bits/ 64 <36000>;
+   opp-microvolt = <82 82 120>;
+   };
+
+   opp@38400 {
+   opp-hz = /bits/ 64 <38400>;
+   opp-microvolt = <83 83 120>;
+   };
+
+   opp@40800 {
+   opp-hz = /bits/ 64 <40800>;
+   opp-microvolt = <84 84 120>;
+   };
+
+   opp@42000 {
+   opp-hz = /bits/ 64 <42000>;
+   opp-microvolt = <85 85 120>;
+   };
+
+   opp@43200 {
+   opp-hz = /bits/ 64 <43200>;
+   opp-microvolt = <86 86 120>;
+   };
+
+   opp@45600 {
+   opp-hz = /bits/ 64 <45600>;
+   opp-microvolt = <87 87 120>;
+   };
+
+   opp@50400 {
+   opp-hz = /bits/ 64 <50400>;
+   opp-microvolt = <89 89 120>;
+   };
+
+   opp@54000 {
+   opp-hz = /bits/ 64 <54000>;
+   opp-microvolt = <91 91 120>;
+   };
+
+   opp@57600 {
+   opp-hz = /bits/ 64 <57600>;
+   opp-microvolt = <93 93 120>;
+   };
+
+   opp@62400 {
+   opp-hz = /bits/ 64 <62400>;
+   opp-microvolt = <95 95 120>;
+   };
+
+   opp@75600 {
+   opp-hz = /bits/ 64 <75600>;
+   opp-microvolt = <104 104 120>;
+   };
+   };
 };
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v5 02/14] drm/panfrost: clean headers in devfreq

2020-07-14 Thread Clément Péron
Don't include not required headers and sort them.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 
 #include 
 #include 
 #include 
 #include 
-#include 
-#include 
 
 #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)
 {
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 04/14] drm/panfrost: introduce panfrost_devfreq struct

2020-07-14 Thread Clément Péron
Introduce a proper panfrost_devfreq to deal with devfreq variables.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 |  4 +-
 4 files changed, 65 insertions(+), 46 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(>devfreq.busy_count) > 0)
-   pfdev->devfreq.busy_time += ktime_sub(now, last);
+   if (atomic_read(>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 = >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 = >pdev->dev;
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
+   struct panfrost_devfreq *pfdevfreq = >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;

[PATCH v4 00/14] Add regulator devfreq support to Panfrost

2020-07-14 Thread Clément Péron
Hi,

This serie cleans and adds regulator support to Panfrost devfreq.
This is mostly based on comment for the freshly introduced lima
devfreq.

We need to add regulator support because on Allwinner the GPU OPP
table defines both frequencies and voltages.

First patches [01-07] should not change the actual behavior
and introduce a proper panfrost_devfreq struct.

Regards,
Clément

Changes since v3:
 - Collect Steven Price reviewed-by tags
 - Rebase on next/master (next-20200709)

Changes since v2:
 - Collect Alyssa Rosenzweig reviewed-by tags
 - Fix opp_set_regulator before adding opp_table (introduce in v2)
 - Call err_fini in case opp_add_table failed

Changes since v1:
 - Collect Steven Price reviewed-by tags
 - Fix spinlock comment
 - Drop OPP clock-name patch
 - Drop device_property_test patch
 - Add rename error labels patch

Clément Péron (14):
  drm/panfrost: avoid static declaration
  drm/panfrost: clean headers in devfreq
  drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle
  drm/panfrost: introduce panfrost_devfreq struct
  drm/panfrost: use spinlock instead of atomic
  drm/panfrost: properly handle error in probe
  drm/panfrost: rename error labels in device_init
  drm/panfrost: move devfreq_init()/fini() in device
  drm/panfrost: dynamically alloc regulators
  drm/panfrost: add regulators to devfreq
  arm64: defconfig: Enable devfreq cooling device
  arm64: dts: allwinner: h6: Add cooling map for GPU
  [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table
  [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always

 .../dts/allwinner/sun50i-h6-beelink-gs1.dts   |   1 +
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 102 ++
 arch/arm64/configs/defconfig  |   1 +
 drivers/gpu/drm/panfrost/panfrost_devfreq.c   | 175 --
 drivers/gpu/drm/panfrost/panfrost_devfreq.h   |  30 ++-
 drivers/gpu/drm/panfrost/panfrost_device.c|  61 +++---
 drivers/gpu/drm/panfrost/panfrost_device.h|  14 +-
 drivers/gpu/drm/panfrost/panfrost_drv.c   |  15 +-
 drivers/gpu/drm/panfrost/panfrost_job.c   |   8 +-
 9 files changed, 295 insertions(+), 112 deletions(-)

-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v4 01/14] drm/panfrost: avoid static declaration

2020-07-14 Thread Clément Péron
This declaration can be avoided so change it.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>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(>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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 04/14] drm/panfrost: introduce panfrost_devfreq struct

2020-07-10 Thread Clément Péron
Introduce a proper panfrost_devfreq to deal with devfreq variables.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>devfreq.busy_count) > 0)
-   pfdev->devfreq.busy_time += ktime_sub(now, last);
+   if (atomic_read(>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 = >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 = >pdev->dev;
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
+   struct panfrost_devfreq *pfdevfreq = >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;

[PATCH v3 14/14] [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always

2020-07-10 Thread Clément Péron
Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
index 3f7ceeb1a767..14257f7476b8 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
@@ -245,6 +245,7 @@ reg_dcdca: dcdca {
};
 
reg_dcdcc: dcdcc {
+   regulator-always-on;
regulator-enable-ramp-delay = <32000>;
regulator-min-microvolt = <81>;
regulator-max-microvolt = <108>;
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 13/14] [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table

2020-07-10 Thread Clément Péron
Add an Operating Performance Points table for the GPU to
enable Dynamic Voltage & Frequency Scaling on the H6.

The voltage range is set with minival voltage set to the target
and the maximal voltage set to 1.2V. This allow DVFS framework to
work properly on board with fixed regulator.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 80 
 1 file changed, 80 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 8f514a2169aa..a69f9e09a829 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -174,6 +174,7 @@ gpu: gpu@180 {
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   operating-points-v2 = <_opp_table>;
#cooling-cells = <2>;
status = "disabled";
};
@@ -1036,4 +1037,83 @@ map0 {
};
};
};
+
+   gpu_opp_table: gpu-opp-table {
+   compatible = "operating-points-v2";
+
+   opp@21600 {
+   opp-hz = /bits/ 64 <21600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@26400 {
+   opp-hz = /bits/ 64 <26400>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@31200 {
+   opp-hz = /bits/ 64 <31200>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@33600 {
+   opp-hz = /bits/ 64 <33600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@36000 {
+   opp-hz = /bits/ 64 <36000>;
+   opp-microvolt = <82 82 120>;
+   };
+
+   opp@38400 {
+   opp-hz = /bits/ 64 <38400>;
+   opp-microvolt = <83 83 120>;
+   };
+
+   opp@40800 {
+   opp-hz = /bits/ 64 <40800>;
+   opp-microvolt = <84 84 120>;
+   };
+
+   opp@42000 {
+   opp-hz = /bits/ 64 <42000>;
+   opp-microvolt = <85 85 120>;
+   };
+
+   opp@43200 {
+   opp-hz = /bits/ 64 <43200>;
+   opp-microvolt = <86 86 120>;
+   };
+
+   opp@45600 {
+   opp-hz = /bits/ 64 <45600>;
+   opp-microvolt = <87 87 120>;
+   };
+
+   opp@50400 {
+   opp-hz = /bits/ 64 <50400>;
+   opp-microvolt = <89 89 120>;
+   };
+
+   opp@54000 {
+   opp-hz = /bits/ 64 <54000>;
+   opp-microvolt = <91 91 120>;
+   };
+
+   opp@57600 {
+   opp-hz = /bits/ 64 <57600>;
+   opp-microvolt = <93 93 120>;
+   };
+
+   opp@62400 {
+   opp-hz = /bits/ 64 <62400>;
+   opp-microvolt = <95 95 120>;
+   };
+
+   opp@75600 {
+   opp-hz = /bits/ 64 <75600>;
+   opp-microvolt = <104 104 120>;
+   };
+   };
 };
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 10/14] drm/panfrost: add regulators to devfreq

2020-07-10 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 drivers/gpu/drm/panfrost/panfrost_devfreq.c | 29 ++---
 drivers/gpu/drm/panfrost/panfrost_devfreq.h |  2 ++
 drivers/gpu/drm/panfrost/panfrost_device.c  | 11 +---
 3 files changed, 34 insertions(+), 8 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 = >pdev->dev;
struct devfreq *devfreq;
+   struct opp_table *opp_table;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = >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(>lock);
@@ -153,6 +169,11 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev)
dev_pm_opp_of_remove_table(>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 
 
 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 0b0fb45aee82..1b5fc9221828 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -223,10 +223,13 @@ int panfrost_device_init(struct panfrost_device *pfdev)
goto out_clk;
}
 
-   err = panfrost_regulator_init(pfdev);
-   if (err) {
-   dev_err(pfdev->dev, "regulator init failed %d\n", err);
-   goto out_devfreq;
+   /* OPP will handle regulators */
+   if (!pfdev->pfdevfreq.opp_of_table_added) {
+   err = panfrost_regulator_init(pfdev);
+   if (err) {
+   dev_err(pfdev->dev, "regulator init failed %d\n", err);
+   goto out_devfreq;
+   }
}
 
err = panfrost_reset_init(pfdev);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 12/14] arm64: dts: allwinner: h6: Add cooling map for GPU

2020-07-10 Thread Clément Péron
Add a simple cooling map for the GPU.

Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 22 
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 78b1361dfbb9..8f514a2169aa 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -174,6 +174,7 @@ gpu: gpu@180 {
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   #cooling-cells = <2>;
status = "disabled";
};
 
@@ -1012,6 +1013,27 @@ gpu-thermal {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = < 1>;
+
+   trips {
+   gpu_alert: gpu-alert {
+   temperature = <85000>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu-crit {
+   temperature = <10>;
+   hysteresis = <0>;
+   type = "critical";
+   };
+   };
+
+   cooling-maps {
+   map0 {
+   trip = <_alert>;
+   cooling-device = < THERMAL_NO_LIMIT 
THERMAL_NO_LIMIT>;
+   };
+   };
};
};
 };
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 06/14] drm/panfrost: properly handle error in probe

2020-07-10 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>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, _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 = >pfdevfreq;
 
-   if (pfdevfreq->cooling)
+   if (pfdevfreq->cooling) {
devfreq_cooling_unregister(pfdevfreq->cooling);
-   dev_pm_opp_of_remove_table(>pdev->dev);
+   pfdevfreq->cooling = NULL;
+   }
+
+   if (pfdevfreq->opp_of_table_added) {
+   dev_pm_opp_of_remove_table(>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;
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 08/14] drm/panfrost: move devfreq_init()/fini() in device

2020-07-10 Thread Clément Péron
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 
Signed-off-by: Clément Péron 
---
 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 cc16d102b275..464da1646398 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -212,10 +212,17 @@ 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) {
dev_err(pfdev->dev, "regulator init failed %d\n", err);
-   goto out_clk;
+   goto out_devfreq;
}
 
err = panfrost_reset_init(pfdev);
@@ -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 882fecc33fdb..4dda68689015 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -14,7 +14,6 @@
 #include 
 
 #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(>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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 11/14] arm64: defconfig: Enable devfreq cooling device

2020-07-10 Thread Clément Péron
Devfreq cooling device framework is used in Panfrost
to throttle GPU in order to regulate its temperature.

Enable this driver for ARM64 SoC.

Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 883e8bace3ed..1b7f9ffdc314 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -501,6 +501,7 @@ CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_INA3221=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
 CONFIG_QORIQ_THERMAL=m
 CONFIG_SUN8I_THERMAL=y
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v3 00/14] Add regulator devfreq support to Panfrost

2020-07-10 Thread Clément Péron
Hi,

On Thu, 9 Jul 2020 at 16:03, Clément Péron  wrote:
>
> Hi,
>
> This serie cleans and adds regulator support to Panfrost devfreq.
> This is mostly based on comment for the freshly introduced lima
> devfreq.
>
> We need to add regulator support because on Allwinner the GPU OPP
> table defines both frequencies and voltages.
>
> First patches [01-07] should not change the actual behavior
> and introduce a proper panfrost_devfreq struct.

Just saw that some changes have been made and pushed to 5.8-rc4.

I will push a v4 up to date.

Regards,
Clement


>
> Regards,
> Clément
>
> Changes since v2:
>  - Collect Alyssa Rosenzweig reviewed-by tags
>  - Fix opp_set_regulator before adding opp_table (introduce in v2)
>  - Call err_fini in case opp_add_table failed
>
> Changes since v1:
>  - Collect Steven Price reviewed-by tags
>  - Fix spinlock comment
>  - Drop OPP clock-name path
>  - Drop device_property_test patch
>  - Add rename error labels patch
>
>
> Clément Péron (14):
>   drm/panfrost: avoid static declaration
>   drm/panfrost: clean headers in devfreq
>   drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle
>   drm/panfrost: introduce panfrost_devfreq struct
>   drm/panfrost: use spinlock instead of atomic
>   drm/panfrost: properly handle error in probe
>   drm/panfrost: rename error labels in device_init
>   drm/panfrost: move devfreq_init()/fini() in device
>   drm/panfrost: dynamically alloc regulators
>   drm/panfrost: add regulators to devfreq
>   arm64: defconfig: Enable devfreq cooling device
>   arm64: dts: allwinner: h6: Add cooling map for GPU
>   [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table
>   [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always
>
>  .../dts/allwinner/sun50i-h6-beelink-gs1.dts   |   1 +
>  arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 102 ++
>  arch/arm64/configs/defconfig  |   1 +
>  drivers/gpu/drm/panfrost/panfrost_devfreq.c   | 175 --
>  drivers/gpu/drm/panfrost/panfrost_devfreq.h   |  30 ++-
>  drivers/gpu/drm/panfrost/panfrost_device.c|  61 +++---
>  drivers/gpu/drm/panfrost/panfrost_device.h|  14 +-
>  drivers/gpu/drm/panfrost/panfrost_drv.c   |  15 +-
>  drivers/gpu/drm/panfrost/panfrost_job.c   |  10 +-
>  9 files changed, 296 insertions(+), 113 deletions(-)
>
> --
> 2.25.1
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 01/14] drm/panfrost: avoid static declaration

2020-07-10 Thread Clément Péron
This declaration can be avoided so change it.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>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(>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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 07/14] drm/panfrost: rename error labels in device_init

2020-07-10 Thread Clément Péron
Rename goto labels in device_init it will be easier to maintain.

Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 8136babd3ba9..cc16d102b275 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -215,57 +215,57 @@ int panfrost_device_init(struct panfrost_device *pfdev)
err = panfrost_regulator_init(pfdev);
if (err) {
dev_err(pfdev->dev, "regulator init failed %d\n", 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;
 }
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 00/14] Add regulator devfreq support to Panfrost

2020-07-10 Thread Clément Péron
Hi,

This serie cleans and adds regulator support to Panfrost devfreq.
This is mostly based on comment for the freshly introduced lima
devfreq.

We need to add regulator support because on Allwinner the GPU OPP
table defines both frequencies and voltages.

First patches [01-07] should not change the actual behavior
and introduce a proper panfrost_devfreq struct.

Regards,
Clément

Changes since v2:
 - Collect Alyssa Rosenzweig reviewed-by tags
 - Fix opp_set_regulator before adding opp_table (introduce in v2)
 - Call err_fini in case opp_add_table failed

Changes since v1:
 - Collect Steven Price reviewed-by tags
 - Fix spinlock comment
 - Drop OPP clock-name path
 - Drop device_property_test patch
 - Add rename error labels patch


Clément Péron (14):
  drm/panfrost: avoid static declaration
  drm/panfrost: clean headers in devfreq
  drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle
  drm/panfrost: introduce panfrost_devfreq struct
  drm/panfrost: use spinlock instead of atomic
  drm/panfrost: properly handle error in probe
  drm/panfrost: rename error labels in device_init
  drm/panfrost: move devfreq_init()/fini() in device
  drm/panfrost: dynamically alloc regulators
  drm/panfrost: add regulators to devfreq
  arm64: defconfig: Enable devfreq cooling device
  arm64: dts: allwinner: h6: Add cooling map for GPU
  [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table
  [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always

 .../dts/allwinner/sun50i-h6-beelink-gs1.dts   |   1 +
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 102 ++
 arch/arm64/configs/defconfig  |   1 +
 drivers/gpu/drm/panfrost/panfrost_devfreq.c   | 175 --
 drivers/gpu/drm/panfrost/panfrost_devfreq.h   |  30 ++-
 drivers/gpu/drm/panfrost/panfrost_device.c|  61 +++---
 drivers/gpu/drm/panfrost/panfrost_device.h|  14 +-
 drivers/gpu/drm/panfrost/panfrost_drv.c   |  15 +-
 drivers/gpu/drm/panfrost/panfrost_job.c   |  10 +-
 9 files changed, 296 insertions(+), 113 deletions(-)

-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 05/14] drm/panfrost: use spinlock instead of atomic

2020-07-10 Thread Clément Péron
Convert busy_count to a simple int protected by spinlock.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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(>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 = >pfdevfreq;
+   unsigned long irqflags;
+
+   status->current_frequency = clk_get_rate(pfdev->clock);
+
+   spin_lock_irqsave(>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(>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(>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(>lock, irqflags);
+
panfrost_devfreq_update_utilization(pfdevfreq);
-   atomic_inc(>busy_count);
+
+   pfdevfreq->busy_count++;
+
+   spin_unlock_irqrestore(>lock, irqflags);
 }
 
 void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq)
 {
-   int count;
+   unsigned long irqflags;
+
+   if (!pfdevfreq->devfreq)
+   return;
+
+   spin_lock_irqsave(>lock, irqflags);
 
panfrost_devfreq_update_utilization(pfdevfreq);
-   count = atomic_dec_if_positive(>busy_count);
-   WARN_ON(count < 0);
+
+   WARN_ON(--pfdevfreq->busy_count < 0);
+
+   spin_unlock_irqrestore(>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 
 #include 
 
 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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 09/14] drm/panfrost: dynamically alloc regulators

2020-07-10 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 464da1646398..0b0fb45aee82 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];
@@ -117,8 +119,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];
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 02/14] drm/panfrost: clean headers in devfreq

2020-07-10 Thread Clément Péron
Don't include not required headers and sort them.

Reviewed-by: Steven Price 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 
 #include 
 #include 
 #include 
 #include 
-#include 
-#include 
 
 #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)
 {
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v3 03/14] drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle

2020-07-10 Thread Clément Péron
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 
Reviewed-by: Alyssa Rosenzweig 
Signed-off-by: Clément Péron 
---
 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 7914b1570841..63e32a9f2749 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(>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(>queue[i].sched.hw_rq_count))
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 04/14] drm/panfrost: introduce panfrost_devfreq struct

2020-07-06 Thread Clément Péron
Introduce a proper panfrost_devfreq to deal with devfreq variables.

Signed-off-by: Clément Péron 
Reviewed-by: Steven Price 
---
 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(>devfreq.busy_count) > 0)
-   pfdev->devfreq.busy_time += ktime_sub(now, last);
+   if (atomic_read(>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 = >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 = >pdev->dev;
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
+   struct panfrost_devfreq *pfdevfreq = >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_dev

[PATCH v2 09/14] drm/panfrost: dynamically alloc regulators

2020-07-06 Thread Clément Péron
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.

Signed-off-by: Clément Péron 
Reviewed-by: Steven Price 
---
 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 464da1646398..0b0fb45aee82 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];
@@ -117,8 +119,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];
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 02/14] drm/panfrost: clean headers in devfreq

2020-07-06 Thread Clément Péron
Don't include not required headers and sort them.

Signed-off-by: Clément Péron 
Reviewed-by: Steven Price 
---
 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 
 #include 
 #include 
 #include 
 #include 
-#include 
-#include 
 
 #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)
 {
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 05/14] drm/panfrost: use spinlock instead of atomic

2020-07-06 Thread Clément Péron
Convert busy_count to a simple int protected by spinlock.

Signed-off-by: Clément Péron 
Reviewed-by: Steven Price 
---
 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(>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 = >pfdevfreq;
+   unsigned long irqflags;
+
+   status->current_frequency = clk_get_rate(pfdev->clock);
+
+   spin_lock_irqsave(>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(>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(>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(>lock, irqflags);
+
panfrost_devfreq_update_utilization(pfdevfreq);
-   atomic_inc(>busy_count);
+
+   pfdevfreq->busy_count++;
+
+   spin_unlock_irqrestore(>lock, irqflags);
 }
 
 void panfrost_devfreq_record_idle(struct panfrost_devfreq *pfdevfreq)
 {
-   int count;
+   unsigned long irqflags;
+
+   if (!pfdevfreq->devfreq)
+   return;
+
+   spin_lock_irqsave(>lock, irqflags);
 
panfrost_devfreq_update_utilization(pfdevfreq);
-   count = atomic_dec_if_positive(>busy_count);
-   WARN_ON(count < 0);
+
+   WARN_ON(--pfdevfreq->busy_count < 0);
+
+   spin_unlock_irqrestore(>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 
 #include 
 
 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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 03/14] drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle

2020-07-06 Thread Clément Péron
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.

Signed-off-by: Clément Péron 
Reviewed-by: Steven Price 
---
 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 7914b1570841..63e32a9f2749 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(>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(>queue[i].sched.hw_rq_count))
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 14/14] [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always

2020-07-06 Thread Clément Péron
Hi,

On Sat, 4 Jul 2020 at 12:25, Clément Péron  wrote:
>
> Signed-off-by: Clément Péron 
> ---
>  arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 +
>  1 file changed, 1 insertion(+)
>
> diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts 
> b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
> index 3f7ceeb1a767..14257f7476b8 100644
> --- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
> +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
> @@ -245,6 +245,7 @@ reg_dcdca: dcdca {
> };
>
> reg_dcdcc: dcdcc {
> +   regulator-always-on;

This patch is normally no more required since this serie:
https://lore.kernel.org/linux-pm/cover.1589528491.git.viresh.ku...@linaro.org/

> regulator-enable-ramp-delay = <32000>;
> regulator-min-microvolt = <81>;
> regulator-max-microvolt = <108>;
> --
> 2.25.1
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 11/14] arm64: defconfig: Enable devfreq cooling device

2020-07-06 Thread Clément Péron
Devfreq cooling device framework is used in Panfrost
to throttle GPU in order to regulate its temperature.

Enable this driver for ARM64 SoC.

Signed-off-by: Clément Péron 
---
 arch/arm64/configs/defconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/configs/defconfig b/arch/arm64/configs/defconfig
index 883e8bace3ed..1b7f9ffdc314 100644
--- a/arch/arm64/configs/defconfig
+++ b/arch/arm64/configs/defconfig
@@ -501,6 +501,7 @@ CONFIG_SENSORS_INA2XX=m
 CONFIG_SENSORS_INA3221=m
 CONFIG_THERMAL_GOV_POWER_ALLOCATOR=y
 CONFIG_CPU_THERMAL=y
+CONFIG_DEVFREQ_THERMAL=y
 CONFIG_THERMAL_EMULATION=y
 CONFIG_QORIQ_THERMAL=m
 CONFIG_SUN8I_THERMAL=y
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 13/14] [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table

2020-07-06 Thread Clément Péron
Add an Operating Performance Points table for the GPU to
enable Dynamic Voltage & Frequency Scaling on the H6.

The voltage range is set with minival voltage set to the target
and the maximal voltage set to 1.2V. This allow DVFS framework to
work properly on board with fixed regulator.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 80 
 1 file changed, 80 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 8f514a2169aa..a69f9e09a829 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -174,6 +174,7 @@ gpu: gpu@180 {
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   operating-points-v2 = <_opp_table>;
#cooling-cells = <2>;
status = "disabled";
};
@@ -1036,4 +1037,83 @@ map0 {
};
};
};
+
+   gpu_opp_table: gpu-opp-table {
+   compatible = "operating-points-v2";
+
+   opp@21600 {
+   opp-hz = /bits/ 64 <21600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@26400 {
+   opp-hz = /bits/ 64 <26400>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@31200 {
+   opp-hz = /bits/ 64 <31200>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@33600 {
+   opp-hz = /bits/ 64 <33600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@36000 {
+   opp-hz = /bits/ 64 <36000>;
+   opp-microvolt = <82 82 120>;
+   };
+
+   opp@38400 {
+   opp-hz = /bits/ 64 <38400>;
+   opp-microvolt = <83 83 120>;
+   };
+
+   opp@40800 {
+   opp-hz = /bits/ 64 <40800>;
+   opp-microvolt = <84 84 120>;
+   };
+
+   opp@42000 {
+   opp-hz = /bits/ 64 <42000>;
+   opp-microvolt = <85 85 120>;
+   };
+
+   opp@43200 {
+   opp-hz = /bits/ 64 <43200>;
+   opp-microvolt = <86 86 120>;
+   };
+
+   opp@45600 {
+   opp-hz = /bits/ 64 <45600>;
+   opp-microvolt = <87 87 120>;
+   };
+
+   opp@50400 {
+   opp-hz = /bits/ 64 <50400>;
+   opp-microvolt = <89 89 120>;
+   };
+
+   opp@54000 {
+   opp-hz = /bits/ 64 <54000>;
+   opp-microvolt = <91 91 120>;
+   };
+
+   opp@57600 {
+   opp-hz = /bits/ 64 <57600>;
+   opp-microvolt = <93 93 120>;
+   };
+
+   opp@62400 {
+   opp-hz = /bits/ 64 <62400>;
+   opp-microvolt = <95 95 120>;
+   };
+
+   opp@75600 {
+   opp-hz = /bits/ 64 <75600>;
+   opp-microvolt = <104 104 120>;
+   };
+   };
 };
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 13/14] [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table

2020-07-06 Thread Clément Péron
Hi Maxime,

On Sat, 4 Jul 2020 at 14:13, Maxime Ripard  wrote:
>
> Hi,
>
> On Sat, Jul 04, 2020 at 12:25:34PM +0200, Clément Péron wrote:
> > Add an Operating Performance Points table for the GPU to
> > enable Dynamic Voltage & Frequency Scaling on the H6.
> >
> > The voltage range is set with minival voltage set to the target
> > and the maximal voltage set to 1.2V. This allow DVFS framework to
> > work properly on board with fixed regulator.
> >
> > Signed-off-by: Clément Péron 
>
> That patch seems reasonable, why shouldn't we merge it?

I didn't test it a lot and last time I did, some frequencies looked unstable.
https://lore.kernel.org/patchwork/cover/1239739/

This series adds regulator support to Panfrost devfreq, I will send a
new one if DVFS on the H6 GPU is stable.

I got this running glmark2 last time
# glmark2-es2-drm
===
glmark2 2017.07
===
OpenGL Information
GL_VENDOR: Panfrost
GL_RENDERER:   Mali T720 (Panfrost)
GL_VERSION:OpenGL ES 2.0 Mesa 20.0.5
===

[   93.550063] panfrost 180.gpu: GPU Fault 0x0088 (UNKNOWN) at
0x80117100
[   94.045401] panfrost 180.gpu: gpu sched timeout, js=0,
config=0x3700, status=0x8, head=0x21d6c00, tail=0x21d6c00,
sched_job=e3c2132f

[  328.871070] panfrost 180.gpu: Unhandled Page fault in AS0 at VA
0x
[  328.871070] Reason: TODO
[  328.871070] raw fault status: 0xAA0003C2
[  328.871070] decoded fault status: SLAVE FAULT
[  328.871070] exception type 0xC2: TRANSLATION_FAULT_LEVEL2
[  328.871070] access type 0x3: WRITE
[  328.871070] source id 0xAA00
[  329.373327] panfrost 180.gpu: gpu sched timeout, js=1,
config=0x3700, status=0x8, head=0xa1a4900, tail=0xa1a4900,
sched_job=7ac31097
[  329.386527] panfrost 180.gpu: js fault, js=0,
status=DATA_INVALID_FAULT, head=0xa1a4c00, tail=0xa1a4c00
[  329.396293] panfrost 180.gpu: gpu sched timeout, js=0,
config=0x3700, status=0x58, head=0xa1a4c00, tail=0xa1a4c00,
sched_job=04c90381
[  329.411521] panfrost 180.gpu: Unhandled Page fault in AS0 at VA
0x
[  329.411521] Reason: TODO
[  329.411521] raw fault status: 0xAA0003C2
[  329.411521] decoded fault status: SLAVE FAULT
[  329.411521] exception type 0xC2: TRANSLATION_FAULT_LEVEL2
[  329.411521] access type 0x3: WRITE
[  329.411521] source id 0xAA00

Regards,
Clement

>
> > ---
> >  arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 80 
> >  1 file changed, 80 insertions(+)
> >
> > diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
> > b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> > index 8f514a2169aa..a69f9e09a829 100644
> > --- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> > +++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
> > @@ -174,6 +174,7 @@ gpu: gpu@180 {
> >   clocks = < CLK_GPU>, < CLK_BUS_GPU>;
> >   clock-names = "core", "bus";
> >   resets = < RST_BUS_GPU>;
> > + operating-points-v2 = <_opp_table>;
> >   #cooling-cells = <2>;
> >   status = "disabled";
> >   };
> > @@ -1036,4 +1037,83 @@ map0 {
> >   };
> >   };
> >   };
> > +
> > + gpu_opp_table: gpu-opp-table {
> > + compatible = "operating-points-v2";
> > +
> > + opp@21600 {
> > + opp-hz = /bits/ 64 <21600>;
> > + opp-microvolt = <81 81 120>;
> > + };
>
> All those nodes will create DTC warnings though.
>
> Maxime
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 10/14] drm/panfrost: add regulators to devfreq

2020-07-06 Thread Clément Péron
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.

Signed-off-by: Clément Péron 
Reviewed-by: Steven Price 
---
 drivers/gpu/drm/panfrost/panfrost_devfreq.c | 19 +++
 drivers/gpu/drm/panfrost/panfrost_devfreq.h |  2 ++
 drivers/gpu/drm/panfrost/panfrost_device.c  | 11 +++
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c 
b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index d9007f44b772..d1e3e9d00a48 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -93,6 +93,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
unsigned long cur_freq;
struct device *dev = >pdev->dev;
struct devfreq *devfreq;
+   struct opp_table *opp_table;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = >pfdevfreq;
 
@@ -105,6 +106,19 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
 
spin_lock_init(>lock);
 
+   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;
+   }
+
panfrost_devfreq_reset(pfdevfreq);
 
cur_freq = clk_get_rate(pfdev->clock);
@@ -153,6 +167,11 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev)
dev_pm_opp_of_remove_table(>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 
 
 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 0b0fb45aee82..1b5fc9221828 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -223,10 +223,13 @@ int panfrost_device_init(struct panfrost_device *pfdev)
goto out_clk;
}
 
-   err = panfrost_regulator_init(pfdev);
-   if (err) {
-   dev_err(pfdev->dev, "regulator init failed %d\n", err);
-   goto out_devfreq;
+   /* OPP will handle regulators */
+   if (!pfdev->pfdevfreq.opp_of_table_added) {
+   err = panfrost_regulator_init(pfdev);
+   if (err) {
+   dev_err(pfdev->dev, "regulator init failed %d\n", err);
+   goto out_devfreq;
+   }
}
 
err = panfrost_reset_init(pfdev);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 12/14] arm64: dts: allwinner: h6: Add cooling map for GPU

2020-07-06 Thread Clément Péron
Add a simple cooling map for the GPU.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 22 
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 78b1361dfbb9..8f514a2169aa 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -174,6 +174,7 @@ gpu: gpu@180 {
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   #cooling-cells = <2>;
status = "disabled";
};
 
@@ -1012,6 +1013,27 @@ gpu-thermal {
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = < 1>;
+
+   trips {
+   gpu_alert: gpu-alert {
+   temperature = <85000>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu-crit {
+   temperature = <10>;
+   hysteresis = <0>;
+   type = "critical";
+   };
+   };
+
+   cooling-maps {
+   map0 {
+   trip = <_alert>;
+   cooling-device = < THERMAL_NO_LIMIT 
THERMAL_NO_LIMIT>;
+   };
+   };
};
};
 };
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 00/14] Add regulator devfreq support to Panfrost

2020-07-06 Thread Clément Péron
Hi,

This serie cleans and adds regulator support to Panfrost devfreq.
This is mostly based on comment for the freshly introduced lima
devfreq.

We need to add regulator support because on Allwinner the GPU OPP
table defines both frequencies and voltages.

First patches [01-07] should not change the actual behavior
and introduce a proper panfrost_devfreq struct.

Regards,
Clément

Clément Péron (14):
  drm/panfrost: avoid static declaration
  drm/panfrost: clean headers in devfreq
  drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle
  drm/panfrost: introduce panfrost_devfreq struct
  drm/panfrost: use spinlock instead of atomic
  drm/panfrost: properly handle error in probe
  drm/panfrost: rename error labels in device_init
  drm/panfrost: move devfreq_init()/fini() in device
  drm/panfrost: dynamically alloc regulators
  drm/panfrost: add regulators to devfreq
  arm64: defconfig: Enable devfreq cooling device
  arm64: dts: allwinner: h6: Add cooling map for GPU
  [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table
  [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always

 .../dts/allwinner/sun50i-h6-beelink-gs1.dts   |   1 +
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 102 +++
 arch/arm64/configs/defconfig  |   1 +
 drivers/gpu/drm/panfrost/panfrost_devfreq.c   | 165 --
 drivers/gpu/drm/panfrost/panfrost_devfreq.h   |  30 +++-
 drivers/gpu/drm/panfrost/panfrost_device.c|  61 ---
 drivers/gpu/drm/panfrost/panfrost_device.h|  14 +-
 drivers/gpu/drm/panfrost/panfrost_drv.c   |  15 +-
 drivers/gpu/drm/panfrost/panfrost_job.c   |  10 +-
 9 files changed, 290 insertions(+), 109 deletions(-)

-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH v2 00/14] Add regulator devfreq support to Panfrost

2020-07-06 Thread Clément Péron
Hi,

On Sat, 4 Jul 2020 at 12:25, Clément Péron  wrote:
>
> Hi,
>
> This serie cleans and adds regulator support to Panfrost devfreq.
> This is mostly based on comment for the freshly introduced lima
> devfreq.
>
> We need to add regulator support because on Allwinner the GPU OPP
> table defines both frequencies and voltages.
>
> First patches [01-07] should not change the actual behavior
> and introduce a proper panfrost_devfreq struct.
>
> Regards,
> Clément

Changes since v1:
 - Collect Steven Price reviewed-by tags
 - Fix spinlock comment
 - Drop OPP clock-name path
 - Drop device_property_test patch
 - Add rename error labels patch

>
> Clément Péron (14):
>   drm/panfrost: avoid static declaration
>   drm/panfrost: clean headers in devfreq
>   drm/panfrost: don't use pfdevfreq.busy_count to know if hw is idle
>   drm/panfrost: introduce panfrost_devfreq struct
>   drm/panfrost: use spinlock instead of atomic
>   drm/panfrost: properly handle error in probe
>   drm/panfrost: rename error labels in device_init
>   drm/panfrost: move devfreq_init()/fini() in device
>   drm/panfrost: dynamically alloc regulators
>   drm/panfrost: add regulators to devfreq
>   arm64: defconfig: Enable devfreq cooling device
>   arm64: dts: allwinner: h6: Add cooling map for GPU
>   [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table
>   [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always
>
>  .../dts/allwinner/sun50i-h6-beelink-gs1.dts   |   1 +
>  arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi  | 102 +++
>  arch/arm64/configs/defconfig  |   1 +
>  drivers/gpu/drm/panfrost/panfrost_devfreq.c   | 165 --
>  drivers/gpu/drm/panfrost/panfrost_devfreq.h   |  30 +++-
>  drivers/gpu/drm/panfrost/panfrost_device.c|  61 ---
>  drivers/gpu/drm/panfrost/panfrost_device.h|  14 +-
>  drivers/gpu/drm/panfrost/panfrost_drv.c   |  15 +-
>  drivers/gpu/drm/panfrost/panfrost_job.c   |  10 +-
>  9 files changed, 290 insertions(+), 109 deletions(-)
>
> --
> 2.25.1
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 07/14] drm/panfrost: rename error labels in device_init

2020-07-06 Thread Clément Péron
Rename goto labels in device_init it will be easier to maintain.

Signed-off-by: Clément Péron 
---
 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 8136babd3ba9..cc16d102b275 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -215,57 +215,57 @@ int panfrost_device_init(struct panfrost_device *pfdev)
err = panfrost_regulator_init(pfdev);
if (err) {
dev_err(pfdev->dev, "regulator init failed %d\n", 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;
 }
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 01/14] drm/panfrost: avoid static declaration

2020-07-06 Thread Clément Péron
This declaration can be avoided so change it.

Signed-off-by: Clément Péron 
Reviewed-by: Steven Price 
---
 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(>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(>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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 08/14] drm/panfrost: move devfreq_init()/fini() in device

2020-07-06 Thread Clément Péron
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.

Signed-off-by: Clément Péron 
---
 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 cc16d102b275..464da1646398 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -212,10 +212,17 @@ 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) {
dev_err(pfdev->dev, "regulator init failed %d\n", err);
-   goto out_clk;
+   goto out_devfreq;
}
 
err = panfrost_reset_init(pfdev);
@@ -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 882fecc33fdb..4dda68689015 100644
--- a/drivers/gpu/drm/panfrost/panfrost_drv.c
+++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
@@ -14,7 +14,6 @@
 #include 
 
 #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(>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);
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 14/14] [DO NOT MERGE] arm64: dts: allwinner: force GPU regulator to be always

2020-07-06 Thread Clément Péron
Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts | 1 +
 1 file changed, 1 insertion(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts 
b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
index 3f7ceeb1a767..14257f7476b8 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6-beelink-gs1.dts
@@ -245,6 +245,7 @@ reg_dcdca: dcdca {
};
 
reg_dcdcc: dcdcc {
+   regulator-always-on;
regulator-enable-ramp-delay = <32000>;
regulator-min-microvolt = <81>;
regulator-max-microvolt = <108>;
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH v2 06/14] drm/panfrost: properly handle error in probe

2020-07-06 Thread Clément Péron
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.

Signed-off-by: Clément Péron 
Reviewed-by: Steven Price 
---
 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(>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, _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 = >pfdevfreq;
 
-   if (pfdevfreq->cooling)
+   if (pfdevfreq->cooling) {
devfreq_cooling_unregister(pfdevfreq->cooling);
-   dev_pm_opp_of_remove_table(>pdev->dev);
+   pfdevfreq->cooling = NULL;
+   }
+
+   if (pfdevfreq->opp_of_table_added) {
+   dev_pm_opp_of_remove_table(>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;
-- 
2.25.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 08/15] drm/panfrost: move devfreq_init()/fini() in device

2020-05-30 Thread Clément Péron
Hi Steven

On Thu, 28 May 2020 at 15:22, Steven Price  wrote:
>
> On 10/05/2020 17:55, Clément Péron wrote:
> > 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.
> >
> > Signed-off-by: Clément Péron 
> > ---
> >   drivers/gpu/drm/panfrost/panfrost_device.c | 37 ++
> >   drivers/gpu/drm/panfrost/panfrost_drv.c| 15 ++---
> >   2 files changed, 25 insertions(+), 27 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/panfrost/panfrost_device.c 
> > b/drivers/gpu/drm/panfrost/panfrost_device.c
> > index 8136babd3ba9..f480127205d6 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_device.c
> > +++ b/drivers/gpu/drm/panfrost/panfrost_device.c
> > @@ -212,59 +212,67 @@ int panfrost_device_init(struct panfrost_device 
> > *pfdev)
> >   return err;
> >   }
> >
> > + err = panfrost_devfreq_init(pfdev);
> > + if (err) {
> > + dev_err(pfdev->dev, "devfreq init failed %d\n", err);
> > + goto err_out0;
> > + }
> > +
> >   err = panfrost_regulator_init(pfdev);
> >   if (err) {
> >   dev_err(pfdev->dev, "regulator init failed %d\n", err);
> > - goto err_out0;
> > + goto err_out1;
>
> NIT: Rather than just renumbering these can we give them sensible names
> so we don't have this sort of refactoring in future?

Agree, I will change that in v2

>
> >   }
> >
> >   err = panfrost_reset_init(pfdev);
> >   if (err) {
> >   dev_err(pfdev->dev, "reset init failed %d\n", err);
> > - goto err_out1;
> > + goto err_out2;
> >   }
> >
> >   err = panfrost_pm_domain_init(pfdev);
> >   if (err)
> > - goto err_out2;
> > + goto err_out3;
> >
> >   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 err_out4;
> >   }
> >
> >   err = panfrost_gpu_init(pfdev);
> >   if (err)
> > - goto err_out3;
> > + goto err_out4;
> >
> >   err = panfrost_mmu_init(pfdev);
> >   if (err)
> > - goto err_out4;
> > + goto err_out5;
> >
> >   err = panfrost_job_init(pfdev);
> >   if (err)
> > - goto err_out5;
> > + goto err_out6;
> >
> >   err = panfrost_perfcnt_init(pfdev);
> >   if (err)
> > - goto err_out6;
> > + goto err_out7;
> >
> >   return 0;
> > -err_out6:
> > +err_out7:
> >   panfrost_job_fini(pfdev);
> > -err_out5:
> > +err_out6:
> >   panfrost_mmu_fini(pfdev);
> > -err_out4:
> > +err_out5:
> >   panfrost_gpu_fini(pfdev);
> > -err_out3:
> > +err_out4:
> >   panfrost_pm_domain_fini(pfdev);
> > -err_out2:
> > +err_out3:
> >   panfrost_reset_fini(pfdev);
> > -err_out1:
> > +err_out2:
> >   panfrost_regulator_fini(pfdev);
> > +err_out1:
> > + panfrost_devfreq_fini(pfdev);
> >   err_out0:
> >   panfrost_clk_fini(pfdev);
> >   return err;
> > @@ -278,6 +286,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 882fecc33fdb..4dda68689015 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_drv.c
> > +++ b/drivers/gpu/drm/panfrost/panfrost_drv.c
> > @@ -14,7 +14,6 @@
> >   #include 
> >
> >   #include "panfrost_device.h"
> > -#include "panfrost_devfreq.

Re: [PATCH 07/15] drm/panfrost: use device_property_present to check for OPP

2020-05-30 Thread Clément Péron
Hi Steven,

On Thu, 28 May 2020 at 15:22, Steven Price  wrote:
>
> On 10/05/2020 17:55, Clément Péron wrote:
> > Instead of expecting an error from dev_pm_opp_of_add_table()
> > do a simple device_property_present() check.
> >
> > Signed-off-by: Clément Péron 
>
> I'm not sure I understand why this is better. We seem to have more code
> to do roughly the same thing just with the hard-coded
> "operating-points-v2" name (if there's ever a 'v3' we'll then have to
> update this).
>
> Is the desire just to get an error on probe if the table is malformed?
> Have you hit this situation? If so this sounds like something which
> would be better fixed in the generic OPP code rather than Panfrost itself.

The idea was to avoid calling devfreq if there is no opp table.
But I think you're right we don't have to check for malformed
device-tree in the driver.

I will drop this patch,

Regards,
Clement


>
> Steve
>
> > ---
> >   drivers/gpu/drm/panfrost/panfrost_devfreq.c | 14 +-
> >   1 file changed, 9 insertions(+), 5 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c 
> > b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > index d9007f44b772..fce21c682414 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > @@ -96,15 +96,19 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
> >   struct thermal_cooling_device *cooling;
> >   struct panfrost_devfreq *pfdevfreq = >pfdevfreq;
> >
> > - ret = dev_pm_opp_of_add_table(dev);
> > - if (ret == -ENODEV) /* Optional, continue without devfreq */
> > + if (!device_property_present(dev, "operating-points-v2"))
> > + /* Optional, continue without devfreq */
> >   return 0;
> > - else if (ret)
> > - return ret;
> > - pfdevfreq->opp_of_table_added = true;
> >
> >   spin_lock_init(>lock);
> >
> > + ret = dev_pm_opp_of_add_table(dev);
> > + if (ret) {
> > + DRM_DEV_ERROR(dev, "Couldn't add OPP table\n");
> > + goto err_fini;
> > + }
> > + pfdevfreq->opp_of_table_added = true;
> > +
> >   panfrost_devfreq_reset(pfdevfreq);
> >
> >   cur_freq = clk_get_rate(pfdev->clock);
> >
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 10/15] drm/panfrost: add regulators to devfreq

2020-05-30 Thread Clément Péron
Hi Steven,

On Thu, 28 May 2020 at 15:23, Steven Price  wrote:
>
> On 10/05/2020 17:55, Clément Péron wrote:
> > 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.
> >
> > Signed-off-by: Clément Péron 
>
> This looks like it should work - thanks for doing this!

Yes but I'm not really happy how it's implemented.

Looks like a bit a workaround but didn't found a better solution.

Thanks for your review,
Clement

>
> Reviewed-by: Steven Price 
>
> > ---
> >   drivers/gpu/drm/panfrost/panfrost_devfreq.c | 19 +++
> >   drivers/gpu/drm/panfrost/panfrost_devfreq.h |  2 ++
> >   drivers/gpu/drm/panfrost/panfrost_device.c  | 11 +++
> >   3 files changed, 28 insertions(+), 4 deletions(-)
> >
> > diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c 
> > b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > index fce21c682414..9ffea0d4a087 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > @@ -93,6 +93,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
> >   unsigned long cur_freq;
> >   struct device *dev = >pdev->dev;
> >   struct devfreq *devfreq;
> > + struct opp_table *opp_table;
> >   struct thermal_cooling_device *cooling;
> >   struct panfrost_devfreq *pfdevfreq = >pfdevfreq;
> >
> > @@ -102,6 +103,19 @@ int panfrost_devfreq_init(struct panfrost_device 
> > *pfdev)
> >
> >   spin_lock_init(>lock);
> >
> > + 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) {
> >   DRM_DEV_ERROR(dev, "Couldn't add OPP table\n");
> > @@ -157,6 +171,11 @@ void panfrost_devfreq_fini(struct panfrost_device 
> > *pfdev)
> >   dev_pm_opp_of_remove_table(>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 add203cb00c2..347cde4786cf 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h
> > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
> > @@ -8,12 +8,14 @@
> >   #include 
> >
> >   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 67eedf64e82d..8b17fb2e3369 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_device.c
> > +++ b/drivers/gpu/drm/panfrost/panfrost_device.c
> > @@ -222,10 +222,13 @@ int panfrost_device_init(struct panfrost_device 
> > *pfdev)
> >   goto err_out0;
> >   }
> >
> > - err = panfrost_regulator_init(pfdev);
> > - if (err) {
> > - dev_err(pfdev->dev, "regulator init failed %d\n", err);
> > - goto err_out1;
> > + /* OPP will handle regulators */
> > + if (!pfdev->pfdevfreq.opp_of_table_added) {
> > + err = panfrost_regulator_init(pfdev);
> > + if (err) {
> > + dev_err(pfdev->dev, "regulator init failed %d\n", 
> > err);
> > + goto err_out1;
> > + }
> >   }
> >
> >   err = panfrost_reset_init(pfdev);
> >
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 11/15] drm/panfrost: set devfreq clock name

2020-05-30 Thread Clément Péron
Hi Steven,

On Thu, 28 May 2020 at 15:23, Steven Price  wrote:
>
> On 10/05/2020 17:55, Clément Péron wrote:
> > Some SoCs have  several clocks defined and the OPP core
> > needs to know the exact name of the clk to use.
> >
> > Set the clock name to "core".
> >
> > Signed-off-by: Clément Péron 
>
> This is unfortunately a regression for the RK3288. The device tree
> binding doesn't require "clock-names", and for the RK3288 it currently
> isn't specified. So this breaks the platform.
>
> Adding the "clock-names" to the device tree 'fixes' it, but we really
> need to keep backwards compatibility.

Yes you're right, thanks for cathing this.

Regards,
Clement

>
> Steve
>
> > ---
> >   drivers/gpu/drm/panfrost/panfrost_devfreq.c | 13 +
> >   drivers/gpu/drm/panfrost/panfrost_devfreq.h |  1 +
> >   2 files changed, 14 insertions(+)
> >
> > diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c 
> > b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > index 9ffea0d4a087..6bf3541b4d53 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
> > @@ -103,6 +103,14 @@ int panfrost_devfreq_init(struct panfrost_device 
> > *pfdev)
> >
> >   spin_lock_init(>lock);
> >
> > + opp_table = dev_pm_opp_set_clkname(dev, "core");
> > + if (IS_ERR(opp_table)) {
> > + ret = PTR_ERR(opp_table);
> > + goto err_fini;
> > + }
> > +
> > + pfdevfreq->clkname_opp_table = opp_table;
> > +
> >   opp_table = dev_pm_opp_set_regulators(dev, pfdev->comp->supply_names,
> > pfdev->comp->num_supplies);
> >   if (IS_ERR(opp_table)) {
> > @@ -176,6 +184,11 @@ void panfrost_devfreq_fini(struct panfrost_device 
> > *pfdev)
> >   dev_pm_opp_put_regulators(pfdevfreq->regulators_opp_table);
> >   pfdevfreq->regulators_opp_table = NULL;
> >   }
> > +
> > + if (pfdevfreq->clkname_opp_table) {
> > + dev_pm_opp_put_clkname(pfdevfreq->clkname_opp_table);
> > + pfdevfreq->clkname_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 347cde4786cf..1f2475e1d034 100644
> > --- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h
> > +++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
> > @@ -16,6 +16,7 @@ struct panfrost_device;
> >   struct panfrost_devfreq {
> >   struct devfreq *devfreq;
> >   struct opp_table *regulators_opp_table;
> > + struct opp_table *clkname_opp_table;
> >   struct thermal_cooling_device *cooling;
> >   bool opp_of_table_added;
> >
> >
>
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


Re: [PATCH 05/15] drm/panfrost: use spinlock instead of atomic

2020-05-30 Thread Clément Péron
Hi Robin,

On Fri, 29 May 2020 at 14:20, Robin Murphy  wrote:
>
> On 2020-05-10 17:55, Clément Péron wrote:
> > Convert busy_count to a simple int protected by spinlock.
>
> A little more reasoning might be nice.

I have follow the modification requested for lima devfreq and clearly
don't have any argument to switch to spinlock.

The Lima Maintainer asked to change witht the following reason :
"Better make this count a normal int which is also protected by the spinlock,
because current implementation can't protect atomic ops for state change
and busy idle check and we are using spinlock already"

>
> > Signed-off-by: Clément Péron 
> > ---
> [...]
> > diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.h 
> > b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
> > index 0697f8d5aa34..e6629900a618 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 
> >   #include 
> >
> >   struct devfreq;
> > @@ -14,10 +15,17 @@ 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, for example by the GP
> > +  * and PP interrupts.
> > +  */
>
> Nit: this comment is clearly wrong, since we only have Job, GPU and MMU
> interrupts here. I guess if there is a race it would be between
> submission/completion/timeout on different job slots.

It's copy/paste from lima I will update it,

>
> Given that, should this actually be considered a fix for 9e62b885f715
> ("drm/panfrost: Simplify devfreq utilisation tracking")?

I can't say if it can be considered as a fix, I didn't see any
improvement on my board before and after this patch.
I'm still facing some issue and didn't have time to fully investigate it.

Thanks for you review,


>
> Robin.
___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 13/15] arm64: dts: allwinner: h6: Add cooling map for GPU

2020-05-11 Thread Clément Péron
Add a simple cooling map for the GPU.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 22 
 1 file changed, 22 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index 2e31632c6ca8..b26f735201c7 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -173,6 +173,7 @@
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   #cooling-cells = <2>;
status = "disabled";
};
 
@@ -1002,6 +1003,27 @@
polling-delay-passive = <0>;
polling-delay = <0>;
thermal-sensors = < 1>;
+
+   trips {
+   gpu_alert: gpu-alert {
+   temperature = <85000>;
+   hysteresis = <2000>;
+   type = "passive";
+   };
+
+   gpu-crit {
+   temperature = <10>;
+   hysteresis = <0>;
+   type = "critical";
+   };
+   };
+
+   cooling-maps {
+   map0 {
+   trip = <_alert>;
+   cooling-device = < THERMAL_NO_LIMIT 
THERMAL_NO_LIMIT>;
+   };
+   };
};
};
 };
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 14/15] [DO NOT MERGE] arm64: dts: allwinner: h6: Add GPU OPP table

2020-05-11 Thread Clément Péron
Add an Operating Performance Points table for the GPU to
enable Dynamic Voltage & Frequency Scaling on the H6.

The voltage range is set with minival voltage set to the target
and the maximal voltage set to 1.2V. This allow DVFS framework to
work properly on board with fixed regulator.

Signed-off-by: Clément Péron 
---
 arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi | 80 
 1 file changed, 80 insertions(+)

diff --git a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi 
b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
index b26f735201c7..85f43a4b651f 100644
--- a/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
+++ b/arch/arm64/boot/dts/allwinner/sun50i-h6.dtsi
@@ -173,6 +173,7 @@
clocks = < CLK_GPU>, < CLK_BUS_GPU>;
clock-names = "core", "bus";
resets = < RST_BUS_GPU>;
+   operating-points-v2 = <_opp_table>;
#cooling-cells = <2>;
status = "disabled";
};
@@ -1026,4 +1027,83 @@
};
};
};
+
+   gpu_opp_table: gpu-opp-table {
+   compatible = "operating-points-v2";
+
+   opp@21600 {
+   opp-hz = /bits/ 64 <21600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@26400 {
+   opp-hz = /bits/ 64 <26400>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@31200 {
+   opp-hz = /bits/ 64 <31200>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@33600 {
+   opp-hz = /bits/ 64 <33600>;
+   opp-microvolt = <81 81 120>;
+   };
+
+   opp@36000 {
+   opp-hz = /bits/ 64 <36000>;
+   opp-microvolt = <82 82 120>;
+   };
+
+   opp@38400 {
+   opp-hz = /bits/ 64 <38400>;
+   opp-microvolt = <83 83 120>;
+   };
+
+   opp@40800 {
+   opp-hz = /bits/ 64 <40800>;
+   opp-microvolt = <84 84 120>;
+   };
+
+   opp@42000 {
+   opp-hz = /bits/ 64 <42000>;
+   opp-microvolt = <85 85 120>;
+   };
+
+   opp@43200 {
+   opp-hz = /bits/ 64 <43200>;
+   opp-microvolt = <86 86 120>;
+   };
+
+   opp@45600 {
+   opp-hz = /bits/ 64 <45600>;
+   opp-microvolt = <87 87 120>;
+   };
+
+   opp@50400 {
+   opp-hz = /bits/ 64 <50400>;
+   opp-microvolt = <89 89 120>;
+   };
+
+   opp@54000 {
+   opp-hz = /bits/ 64 <54000>;
+   opp-microvolt = <91 91 120>;
+   };
+
+   opp@57600 {
+   opp-hz = /bits/ 64 <57600>;
+   opp-microvolt = <93 93 120>;
+   };
+
+   opp@62400 {
+   opp-hz = /bits/ 64 <62400>;
+   opp-microvolt = <95 95 120>;
+   };
+
+   opp@75600 {
+   opp-hz = /bits/ 64 <75600>;
+   opp-microvolt = <104 104 120>;
+   };
+   };
 };
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 06/15] drm/panfrost: properly handle error in probe

2020-05-11 Thread Clément Péron
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.

Signed-off-by: Clément Péron 
---
 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(>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, _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 = >pfdevfreq;
 
-   if (pfdevfreq->cooling)
+   if (pfdevfreq->cooling) {
devfreq_cooling_unregister(pfdevfreq->cooling);
-   dev_pm_opp_of_remove_table(>pdev->dev);
+   pfdevfreq->cooling = NULL;
+   }
+
+   if (pfdevfreq->opp_of_table_added) {
+   dev_pm_opp_of_remove_table(>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 e6629900a618..add203cb00c2 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;
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


[PATCH 04/15] drm/panfrost: introduce panfrost_devfreq struct

2020-05-11 Thread Clément Péron
Introduce a proper panfrost_devfreq to deal with devfreq variables.

Signed-off-by: Clément Péron 
---
 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(>devfreq.busy_count) > 0)
-   pfdev->devfreq.busy_time += ktime_sub(now, last);
+   if (atomic_read(>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 = >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 = >pdev->dev;
struct devfreq *devfreq;
struct thermal_cooling_device *cooling;
+   struct panfrost_devfreq *pfdevfreq = >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 *

[PATCH 10/15] drm/panfrost: add regulators to devfreq

2020-05-11 Thread Clément Péron
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.

Signed-off-by: Clément Péron 
---
 drivers/gpu/drm/panfrost/panfrost_devfreq.c | 19 +++
 drivers/gpu/drm/panfrost/panfrost_devfreq.h |  2 ++
 drivers/gpu/drm/panfrost/panfrost_device.c  | 11 +++
 3 files changed, 28 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/panfrost/panfrost_devfreq.c 
b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
index fce21c682414..9ffea0d4a087 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.c
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.c
@@ -93,6 +93,7 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
unsigned long cur_freq;
struct device *dev = >pdev->dev;
struct devfreq *devfreq;
+   struct opp_table *opp_table;
struct thermal_cooling_device *cooling;
struct panfrost_devfreq *pfdevfreq = >pfdevfreq;
 
@@ -102,6 +103,19 @@ int panfrost_devfreq_init(struct panfrost_device *pfdev)
 
spin_lock_init(>lock);
 
+   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) {
DRM_DEV_ERROR(dev, "Couldn't add OPP table\n");
@@ -157,6 +171,11 @@ void panfrost_devfreq_fini(struct panfrost_device *pfdev)
dev_pm_opp_of_remove_table(>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 add203cb00c2..347cde4786cf 100644
--- a/drivers/gpu/drm/panfrost/panfrost_devfreq.h
+++ b/drivers/gpu/drm/panfrost/panfrost_devfreq.h
@@ -8,12 +8,14 @@
 #include 
 
 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 67eedf64e82d..8b17fb2e3369 100644
--- a/drivers/gpu/drm/panfrost/panfrost_device.c
+++ b/drivers/gpu/drm/panfrost/panfrost_device.c
@@ -222,10 +222,13 @@ int panfrost_device_init(struct panfrost_device *pfdev)
goto err_out0;
}
 
-   err = panfrost_regulator_init(pfdev);
-   if (err) {
-   dev_err(pfdev->dev, "regulator init failed %d\n", err);
-   goto err_out1;
+   /* OPP will handle regulators */
+   if (!pfdev->pfdevfreq.opp_of_table_added) {
+   err = panfrost_regulator_init(pfdev);
+   if (err) {
+   dev_err(pfdev->dev, "regulator init failed %d\n", err);
+   goto err_out1;
+   }
}
 
err = panfrost_reset_init(pfdev);
-- 
2.20.1

___
dri-devel mailing list
dri-devel@lists.freedesktop.org
https://lists.freedesktop.org/mailman/listinfo/dri-devel


  1   2   >