Re: DisplayPort: handling of HPD events / link training

2024-07-16 Thread Thomas Zimmermann

Hi

Am 16.07.24 um 18:35 schrieb Dmitry Baryshkov:

On Tue, 16 Jul 2024 at 18:58, Thomas Zimmermann  wrote:

Hi

Am 27.02.24 um 23:40 schrieb Dmitry Baryshkov:

Hello,

We are currently looking at checking and/or possibly redesigning the
way the MSM DRM driver handles the HPD events and link training.

After a quick glance at the drivers implementing DP support, I noticed
following main approaches:
- Perform link training at the atomic_enable time, don't report
failures (mtk, analogix, zynqmp, tegra, nouveau)
- Perform link training at the atomic_enable time, report errors using
link_status property (i915, mhdp8546)
- Perform link training on the plug event (msm, it8605).
- Perform link training from the DPMS handler, also calling it from
the enable callback (AMDGPU, radeon).

It looks like the majority wins and we should move HPD to
atomic_enable time. Is that assumption correct?

Did you ever receive an answer to this question? I currently investigate
ast's DP code, which does link training as part of detecting the
connector state (in detect_ctx). But most other drivers do this in
atomic_enable. I wonder if ast should follow.

Short answer: yes, the only proper place to do it is atomic_enable().


Thanks.



Long answer: I don't see a way to retrigger link training in ast_dp.c
Without such change you are just shifting things around. The
end-result of moving link-training to atomic_enable() is that each
enable can trigger link training, possibly lowering the link rate,
etc. if link training is just a status bit from the firmware that we
don't control, it doesn't make real-real sense to move it.


I have to think about what to do. People tend to copy existing drivers, 
which alone might be a good argument for using atomic_enable. The link 
training is indeed just a flag that is set by the firmware. I think it's 
possible to re-trigger training by powering the port down and up again. 
atomic_enable could likely do that. The hardware is also somewhat buggy 
and not fully standard conformant.


Best regards
Thomas




Best regards
Thomas


Also two related questions:
- Is there a plan to actually make use of the link_status property?
Intel presented it at FOSDEM 2018, but since that time it was not
picked up by other drivers.

- Is there any plan to create generic DP link training helpers? After
glancing through the DP drivers there is a lot of similar code in the
link training functions, with minor differences here and there. And
it's those minor differences that bug me. It means that drivers might
respond differently to similar devices. Or that there might be minor
bugs here and there.


--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)





--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)



Re: DisplayPort: handling of HPD events / link training

2024-07-16 Thread Thomas Zimmermann

Hi

Am 27.02.24 um 23:40 schrieb Dmitry Baryshkov:

Hello,

We are currently looking at checking and/or possibly redesigning the
way the MSM DRM driver handles the HPD events and link training.

After a quick glance at the drivers implementing DP support, I noticed
following main approaches:
- Perform link training at the atomic_enable time, don't report
failures (mtk, analogix, zynqmp, tegra, nouveau)
- Perform link training at the atomic_enable time, report errors using
link_status property (i915, mhdp8546)
- Perform link training on the plug event (msm, it8605).
- Perform link training from the DPMS handler, also calling it from
the enable callback (AMDGPU, radeon).

It looks like the majority wins and we should move HPD to
atomic_enable time. Is that assumption correct?


Did you ever receive an answer to this question? I currently investigate 
ast's DP code, which does link training as part of detecting the 
connector state (in detect_ctx). But most other drivers do this in 
atomic_enable. I wonder if ast should follow.


Best regards
Thomas



Also two related questions:
- Is there a plan to actually make use of the link_status property?
Intel presented it at FOSDEM 2018, but since that time it was not
picked up by other drivers.

- Is there any plan to create generic DP link training helpers? After
glancing through the DP drivers there is a lot of similar code in the
link training functions, with minor differences here and there. And
it's those minor differences that bug me. It means that drivers might
respond differently to similar devices. Or that there might be minor
bugs here and there.



--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)



Re: [PATCH v5] drm/display: split DSC helpers from DP helpers

2024-06-26 Thread Thomas Zimmermann

Hi

Am 23.06.24 um 00:44 schrieb Dmitry Baryshkov:

Currently the DRM DSC functions are selected by the
DRM_DISPLAY_DP_HELPER Kconfig symbol. This is not optimal, since the DSI
code (both panel and host drivers) end up selecting the seemingly
irrelevant DP helpers. Split the DSC code to be guarded by the separate
DRM_DISPLAY_DSC_HELPER Kconfig symbol.

Reviewed-by: Jessica Zhang 
Reviewed-by: Marijn Suijten 
Signed-off-by: Dmitry Baryshkov 
---
To: Alex Deucher 
To: Christian König 
To: Pan, Xinhui 
To: David Airlie 
To: Daniel Vetter 
To: Maarten Lankhorst 
To: Maxime Ripard 
To: Thomas Zimmermann 
To: Jani Nikula 
To: Joonas Lahtinen 
To: Rodrigo Vivi 
To: Tvrtko Ursulin 
To: Rob Clark 
To: Abhinav Kumar 
To: Sean Paul 
To: Marijn Suijten 
To: Neil Armstrong 
To: Jessica Zhang 
Cc: amd-...@lists.freedesktop.org
Cc: dri-de...@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org
Cc: intel-...@lists.freedesktop.org
Cc: linux-arm-...@vger.kernel.org
Cc: freedreno@lists.freedesktop.org
Signed-off-by: Dmitry Baryshkov 

Changes in v5:
- Drop applied patches
- Link to v4: 
https://lore.kernel.org/r/20240528-panel-sw43408-fix-v4-0-330b42445...@linaro.org

Changes in v4:
- Reoder patches so that fixes come first, to be able to land them to
   drm-misc-fixes
- Link to v3: 
https://lore.kernel.org/r/20240522-panel-sw43408-fix-v3-0-6902285ad...@linaro.org

Changes in v3:
- Split DRM_DISPLAY_DSC_HELPER from DRM_DISPLAY_DP_HELPER
- Added missing Fixes tags
- Link to v2: 
https://lore.kernel.org/r/20240510-panel-sw43408-fix-v2-0-d1ef91ee1...@linaro.org

Changes in v2:
- use SELECT instead of DEPEND to follow the reverted Kconfig changes
- Link to v1: 
https://lore.kernel.org/r/20240420-panel-sw43408-fix-v1-0-b282ff725...@linaro.org
---
  drivers/gpu/drm/amd/amdgpu/Kconfig | 1 +
  drivers/gpu/drm/display/Kconfig| 6 ++
  drivers/gpu/drm/display/Makefile   | 3 ++-
  drivers/gpu/drm/i915/Kconfig   | 1 +
  drivers/gpu/drm/msm/Kconfig| 1 +
  drivers/gpu/drm/panel/Kconfig  | 6 +++---
  6 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/amd/amdgpu/Kconfig 
b/drivers/gpu/drm/amd/amdgpu/Kconfig
index 4232ab27f990..5933ca8c6b96 100644
--- a/drivers/gpu/drm/amd/amdgpu/Kconfig
+++ b/drivers/gpu/drm/amd/amdgpu/Kconfig
@@ -6,6 +6,7 @@ config DRM_AMDGPU
depends on !UML
select FW_LOADER
select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_DSC_HELPER
select DRM_DISPLAY_HDMI_HELPER
select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HELPER
diff --git a/drivers/gpu/drm/display/Kconfig b/drivers/gpu/drm/display/Kconfig
index 479e62690d75..a2e42014ffe0 100644
--- a/drivers/gpu/drm/display/Kconfig
+++ b/drivers/gpu/drm/display/Kconfig
@@ -59,6 +59,12 @@ config DRM_DISPLAY_DP_TUNNEL_STATE_DEBUG
  
  	  If in doubt, say "N".
  
+config DRM_DISPLAY_DSC_HELPER

+   bool
+   depends on DRM_DISPLAY_HELPER
+   help
+ DRM display helpers for VESA DSC (used by DSI and DisplayPort).
+
  config DRM_DISPLAY_HDCP_HELPER
bool
depends on DRM_DISPLAY_HELPER
diff --git a/drivers/gpu/drm/display/Makefile b/drivers/gpu/drm/display/Makefile
index 629df2f4d322..df8f22c7e916 100644
--- a/drivers/gpu/drm/display/Makefile
+++ b/drivers/gpu/drm/display/Makefile
@@ -6,7 +6,8 @@ drm_display_helper-y := drm_display_helper_mod.o
  drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_HELPER) += \
drm_dp_dual_mode_helper.o \
drm_dp_helper.o \
-   drm_dp_mst_topology.o \
+   drm_dp_mst_topology.o
+drm_display_helper-$(CONFIG_DRM_DISPLAY_DSC_HELPER) += \
drm_dsc_helper.o
  drm_display_helper-$(CONFIG_DRM_DISPLAY_DP_TUNNEL) += \


nit: DSC_HELPER should go after DP_TUNNEL to keep it sorted alphabetically.

Best regards
Thomas


drm_dp_tunnel.o
diff --git a/drivers/gpu/drm/i915/Kconfig b/drivers/gpu/drm/i915/Kconfig
index faa253b27664..db400aad88fa 100644
--- a/drivers/gpu/drm/i915/Kconfig
+++ b/drivers/gpu/drm/i915/Kconfig
@@ -11,6 +11,7 @@ config DRM_I915
select SHMEM
select TMPFS
select DRM_DISPLAY_DP_HELPER
+   select DRM_DISPLAY_DSC_HELPER
select DRM_DISPLAY_HDCP_HELPER
select DRM_DISPLAY_HDMI_HELPER
select DRM_DISPLAY_HELPER
diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 1931ecf73e32..6dcd26180611 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -111,6 +111,7 @@ config DRM_MSM_DSI
depends on DRM_MSM
select DRM_PANEL
select DRM_MIPI_DSI
+   select DRM_DISPLAY_DSC_HELPER
default y
help
  Choose this option if you have a need for MIPI DSI connector
diff --git a/drivers/gpu/drm/panel/Kconfig b/drivers/gpu/drm/panel/Kconfig
index bf4eadfe21cb..afae8b130e9a 100644
--- a/drivers/gpu/drm/panel/Kconfig
+++ b/drivers/gpu/drm/panel/Kconfig
@@ -349,7 +349,7 @@ config DRM_PANEL_LG_SW43408
depends on OF
depends on DR

Re: [PATCH 00/13] drm: Fix reservation locking for pin/unpin and console

2024-03-06 Thread Thomas Zimmermann

Hi

Am 05.03.24 um 22:58 schrieb Dmitry Osipenko:

On 2/27/24 13:14, Thomas Zimmermann wrote:

Dma-buf locking semantics require the caller of pin and unpin to hold
the buffer's reservation lock. Fix DRM to adhere to the specs. This
enables to fix the locking in DRM's console emulation. Similar changes
for vmap and mmap have been posted at [1][2]

Most DRM drivers and memory managers acquire the buffer object's
reservation lock within their GEM pin and unpin callbacks. This
violates dma-buf locking semantics. We get away with it because PRIME
does not provide pin/unpin, but attach/detach, for which the locking
semantics is correct.

Patches 1 to 8 rework DRM GEM code in various implementations to
acquire the reservation lock when entering the pin and unpin callbacks.
This prepares them for the next patch. Drivers that are not affected
by these patches either don't acquire the reservation lock (amdgpu)
or don't need preparation (loongson).

Patch 9 moves reservation locking from the GEM pin/unpin callbacks
into drm_gem_pin() and drm_gem_unpin(). As PRIME uses these functions
internally it still gets the reservation lock.

With the updated GEM callbacks, the rest of the patchset fixes the
fbdev emulation's buffer locking. Fbdev emulation needs to keep its
GEM buffer object inplace while updating its content. This required
a implicit pinning and apparently amdgpu didn't do this at all.

Patch 10 introduces drm_client_buffer_vmap_local() and _vunmap_local().
The former function map a GEM buffer into the kernel's address space
with regular vmap operations, but keeps holding the reservation lock.
The _vunmap_local() helper undoes the vmap and releases the lock. The
updated GEM callbacks make this possible. Between the two calls, the
fbdev emulation can update the buffer content without have the buffer
moved or evicted. Update fbdev-generic to use vmap_local helpers,
which fix amdgpu. The idea of adding a "local vmap" has previously been
attempted at [3] in a different form.

Patch 11 adds implicit pinning to the DRM client's regular vmap
helper so that long-term vmap'ed buffers won't be evicted. This only
affects fbdev-dma, but GEM DMA helpers don't require pinning. So
there are no practical changes.

Patches 12 and 13 remove implicit pinning from the vmap and vunmap
operations in gem-vram and qxl. These pin operations are not supposed
to be part of vmap code, but were required to keep the buffers in place
for fbdev emulation. With the conversion o ffbdev-generic to to
vmap_local helpers, that code can finally be removed.

Tested with amdgpu, nouveau, radeon, simpledrm and vc4.

[1] https://patchwork.freedesktop.org/series/106371/
[2] https://patchwork.freedesktop.org/series/116001/
[3] https://patchwork.freedesktop.org/series/84732/

Thomas Zimmermann (13):
   drm/gem-shmem: Acquire reservation lock in GEM pin/unpin callbacks
   drm/gem-vram: Acquire reservation lock in GEM pin/unpin callbacks
   drm/msm: Provide msm_gem_get_pages_locked()
   drm/msm: Acquire reservation lock in GEM pin/unpin callback
   drm/nouveau: Provide nouveau_bo_{pin,unpin}_locked()
   drm/nouveau: Acquire reservation lock in GEM pin/unpin callbacks
   drm/qxl: Provide qxl_bo_{pin,unpin}_locked()
   drm/qxl: Acquire reservation lock in GEM pin/unpin callbacks
   drm/gem: Acquire reservation lock in drm_gem_{pin/unpin}()
   drm/fbdev-generic: Fix locking with drm_client_buffer_vmap_local()
   drm/client: Pin vmap'ed GEM buffers
   drm/gem-vram: Do not pin buffer objects for vmap
   drm/qxl: Do not pin buffer objects for vmap

The patches look good. I gave them fbtest on virtio-gpu, no problems
spotted.

Reviewed-by: Dmitry Osipenko 
Tested-by: Dmitry Osipenko  # virtio-gpu


Great, thanks a lot. If no other reviews come in, I'll land the patchset 
within the next days.


Best regards
Thomas





--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)



Re: [PATCH 00/13] drm: Fix reservation locking for pin/unpin and console

2024-02-28 Thread Thomas Zimmermann

Hi

Am 27.02.24 um 19:14 schrieb Dmitry Osipenko:

Hello,

Thank you for the patches!

On 2/27/24 13:14, Thomas Zimmermann wrote:

Dma-buf locking semantics require the caller of pin and unpin to hold
the buffer's reservation lock. Fix DRM to adhere to the specs. This
enables to fix the locking in DRM's console emulation. Similar changes
for vmap and mmap have been posted at [1][2]

Most DRM drivers and memory managers acquire the buffer object's
reservation lock within their GEM pin and unpin callbacks. This
violates dma-buf locking semantics. We get away with it because PRIME
does not provide pin/unpin, but attach/detach, for which the locking
semantics is correct.

Patches 1 to 8 rework DRM GEM code in various implementations to
acquire the reservation lock when entering the pin and unpin callbacks.
This prepares them for the next patch. Drivers that are not affected
by these patches either don't acquire the reservation lock (amdgpu)
or don't need preparation (loongson).

Patch 9 moves reservation locking from the GEM pin/unpin callbacks
into drm_gem_pin() and drm_gem_unpin(). As PRIME uses these functions
internally it still gets the reservation lock.

With the updated GEM callbacks, the rest of the patchset fixes the
fbdev emulation's buffer locking. Fbdev emulation needs to keep its
GEM buffer object inplace while updating its content. This required
a implicit pinning and apparently amdgpu didn't do this at all.

Patch 10 introduces drm_client_buffer_vmap_local() and _vunmap_local().
The former function map a GEM buffer into the kernel's address space
with regular vmap operations, but keeps holding the reservation lock.
The _vunmap_local() helper undoes the vmap and releases the lock. The
updated GEM callbacks make this possible. Between the two calls, the
fbdev emulation can update the buffer content without have the buffer
moved or evicted. Update fbdev-generic to use vmap_local helpers,
which fix amdgpu. The idea of adding a "local vmap" has previously been
attempted at [3] in a different form.

Patch 11 adds implicit pinning to the DRM client's regular vmap
helper so that long-term vmap'ed buffers won't be evicted. This only
affects fbdev-dma, but GEM DMA helpers don't require pinning. So
there are no practical changes.

Patches 12 and 13 remove implicit pinning from the vmap and vunmap
operations in gem-vram and qxl. These pin operations are not supposed
to be part of vmap code, but were required to keep the buffers in place
for fbdev emulation. With the conversion o ffbdev-generic to to
vmap_local helpers, that code can finally be removed.

Isn't it a common behaviour for all DRM drivers to implicitly pin BO
while it's vmapped? I was sure it should be common /o\


That's what I originally thought as well, but the intention is for pin 
and vmap to be distinct operation. So far each driver has been 
different, as you probably know best from your vmap refactoring. :)




Why would you want to kmap BO that isn't pinned?


Pinning places the buffer object for the GPU. As a side effect, the 
buffer is then kept in place, which enables vmap. So pinning only makes 
sense for buffer objects that never move (shmem, dma). That's what patch 
11 is for.




Shouldn't TTM's vmap() be changed to do the pinning?


I don't think so. One problem is that pinning needs a memory area (vram, 
GTT, system ram, etc) specified, which vmap simply doesn't know about. 
That has been a problem for fbdev emulation at some point. Our fbdev 
code tried to pin as part of vmap, but chose the wrong area and suddenly 
the GPU could not see the buffer object any longer.  So the next best 
thing for vmap was to pin the buffer object where ever it is currently 
located. That is what gem-vram and qxl did so far. And of course, the 
fbdev code needs to unpin and vunmap the buffer object quickly, so that 
it can be relocated if the GPU needs it.  Hence, the vmap_local 
interface removes such short-term pinning in favor of holding the 
reservation lock.




I missed that TTM doesn't pin BO on vmap() and now surprised to see it.
It should be a rather serious problem requiring backporting of the
fixes, but I don't see the fixes tags on the patches (?)


No chance TBH. The old code has worked for years and backporting all 
this would require your vmap patches at a minimum.


Except maybe for amdgpu. It uses fbdev-generic, which requires pinning, 
but amdgpu doesn't pin. That looks fishy, but I'm not aware of any bug 
reports either. I guess, a quick workaround could fix older amdgpu if 
necessary.


Best regards
Thomas





--
--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)



Re: [PATCH 00/13] drm: Fix reservation locking for pin/unpin and console

2024-02-27 Thread Thomas Zimmermann

Hi

Am 27.02.24 um 15:03 schrieb Christian König:

Nice, looks totally valid to me.

Feel free to add to patch #2, #9, #10, #11 and #12 Reviewed-by: 
Christian König 


And Acked-by: Christian König  to the rest.


Oh, wow. That was quick! Thanks a lot.

Best regards
Thomas



Regards,
Christian.

Am 27.02.24 um 11:14 schrieb Thomas Zimmermann:

Dma-buf locking semantics require the caller of pin and unpin to hold
the buffer's reservation lock. Fix DRM to adhere to the specs. This
enables to fix the locking in DRM's console emulation. Similar changes
for vmap and mmap have been posted at [1][2]

Most DRM drivers and memory managers acquire the buffer object's
reservation lock within their GEM pin and unpin callbacks. This
violates dma-buf locking semantics. We get away with it because PRIME
does not provide pin/unpin, but attach/detach, for which the locking
semantics is correct.

Patches 1 to 8 rework DRM GEM code in various implementations to
acquire the reservation lock when entering the pin and unpin callbacks.
This prepares them for the next patch. Drivers that are not affected
by these patches either don't acquire the reservation lock (amdgpu)
or don't need preparation (loongson).

Patch 9 moves reservation locking from the GEM pin/unpin callbacks
into drm_gem_pin() and drm_gem_unpin(). As PRIME uses these functions
internally it still gets the reservation lock.

With the updated GEM callbacks, the rest of the patchset fixes the
fbdev emulation's buffer locking. Fbdev emulation needs to keep its
GEM buffer object inplace while updating its content. This required
a implicit pinning and apparently amdgpu didn't do this at all.

Patch 10 introduces drm_client_buffer_vmap_local() and _vunmap_local().
The former function map a GEM buffer into the kernel's address space
with regular vmap operations, but keeps holding the reservation lock.
The _vunmap_local() helper undoes the vmap and releases the lock. The
updated GEM callbacks make this possible. Between the two calls, the
fbdev emulation can update the buffer content without have the buffer
moved or evicted. Update fbdev-generic to use vmap_local helpers,
which fix amdgpu. The idea of adding a "local vmap" has previously been
attempted at [3] in a different form.

Patch 11 adds implicit pinning to the DRM client's regular vmap
helper so that long-term vmap'ed buffers won't be evicted. This only
affects fbdev-dma, but GEM DMA helpers don't require pinning. So
there are no practical changes.

Patches 12 and 13 remove implicit pinning from the vmap and vunmap
operations in gem-vram and qxl. These pin operations are not supposed
to be part of vmap code, but were required to keep the buffers in place
for fbdev emulation. With the conversion o ffbdev-generic to to
vmap_local helpers, that code can finally be removed.

Tested with amdgpu, nouveau, radeon, simpledrm and vc4.

[1] https://patchwork.freedesktop.org/series/106371/
[2] https://patchwork.freedesktop.org/series/116001/
[3] https://patchwork.freedesktop.org/series/84732/

Thomas Zimmermann (13):
   drm/gem-shmem: Acquire reservation lock in GEM pin/unpin callbacks
   drm/gem-vram: Acquire reservation lock in GEM pin/unpin callbacks
   drm/msm: Provide msm_gem_get_pages_locked()
   drm/msm: Acquire reservation lock in GEM pin/unpin callback
   drm/nouveau: Provide nouveau_bo_{pin,unpin}_locked()
   drm/nouveau: Acquire reservation lock in GEM pin/unpin callbacks
   drm/qxl: Provide qxl_bo_{pin,unpin}_locked()
   drm/qxl: Acquire reservation lock in GEM pin/unpin callbacks
   drm/gem: Acquire reservation lock in drm_gem_{pin/unpin}()
   drm/fbdev-generic: Fix locking with drm_client_buffer_vmap_local()
   drm/client: Pin vmap'ed GEM buffers
   drm/gem-vram: Do not pin buffer objects for vmap
   drm/qxl: Do not pin buffer objects for vmap

  drivers/gpu/drm/drm_client.c    |  92 ++---
  drivers/gpu/drm/drm_fbdev_generic.c |   4 +-
  drivers/gpu/drm/drm_gem.c   |  34 +++-
  drivers/gpu/drm/drm_gem_shmem_helper.c  |   6 +-
  drivers/gpu/drm/drm_gem_vram_helper.c   | 101 ++--
  drivers/gpu/drm/drm_internal.h  |   2 +
  drivers/gpu/drm/loongson/lsdc_gem.c |  13 +--
  drivers/gpu/drm/msm/msm_gem.c   |  20 ++---
  drivers/gpu/drm/msm/msm_gem.h   |   4 +-
  drivers/gpu/drm/msm/msm_gem_prime.c |  20 +++--
  drivers/gpu/drm/nouveau/nouveau_bo.c    |  43 +++---
  drivers/gpu/drm/nouveau/nouveau_bo.h    |   2 +
  drivers/gpu/drm/nouveau/nouveau_prime.c |   8 +-
  drivers/gpu/drm/qxl/qxl_object.c    |  26 +++---
  drivers/gpu/drm/qxl/qxl_object.h    |   2 +
  drivers/gpu/drm/qxl/qxl_prime.c |   4 +-
  drivers/gpu/drm/radeon/radeon_prime.c   |  11 ---
  drivers/gpu/drm/vmwgfx/vmwgfx_gem.c |  25 ++
  include/drm/drm_client.h    |  10 +++
  include/drm/drm_gem.h   |   3 +
  include/drm/drm_

[PATCH 13/13] drm/qxl: Do not pin buffer objects for vmap

2024-02-27 Thread Thomas Zimmermann
Pin and vmap are distinct operations. Do not perform a pin as part
of the vmap call. This used to be necessary to keep the fbdev buffer
in place while it is being updated. Fbdev emulation has meanwhile
been fixed to lock the buffer correctly. Same for vunmap.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/qxl/qxl_object.c | 5 -
 1 file changed, 5 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c
index 39218e979a807..5893e27a7ae50 100644
--- a/drivers/gpu/drm/qxl/qxl_object.c
+++ b/drivers/gpu/drm/qxl/qxl_object.c
@@ -164,10 +164,6 @@ int qxl_bo_vmap_locked(struct qxl_bo *bo, struct iosys_map 
*map)
goto out;
}
 
-   r = qxl_bo_pin_locked(bo);
-   if (r)
-   return r;
-
r = ttm_bo_vmap(&bo->tbo, &bo->map);
if (r) {
qxl_bo_unpin_locked(bo);
@@ -243,7 +239,6 @@ void qxl_bo_vunmap_locked(struct qxl_bo *bo)
return;
bo->kptr = NULL;
ttm_bo_vunmap(&bo->tbo, &bo->map);
-   qxl_bo_unpin_locked(bo);
 }
 
 int qxl_bo_vunmap(struct qxl_bo *bo)
-- 
2.43.2



[PATCH 12/13] drm/gem-vram: Do not pin buffer objects for vmap

2024-02-27 Thread Thomas Zimmermann
Pin and vmap are distinct operations. Do not perform a pin as part
of the vmap call. This used to be necessary to keep the fbdev buffer
in place while it is being updated. Fbdev emulation has meanwhile
been fixed to lock the buffer correctly. Same for vunmap.

For refactoring the code, remove the pin calls from the helper's
vmap implementation in drm_gem_vram_vmap() and inline the call to
drm_gem_vram_kmap_locked(). This gives a vmap helper that only
maps the buffer object's memory pages without pinning or locking.
Do a similar refactoring for vunmap.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_gem_vram_helper.c | 90 ++-
 1 file changed, 32 insertions(+), 58 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
b/drivers/gpu/drm/drm_gem_vram_helper.c
index 5a16b3e0a4134..45650b9b3de91 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -368,11 +368,28 @@ int drm_gem_vram_unpin(struct drm_gem_vram_object *gbo)
 }
 EXPORT_SYMBOL(drm_gem_vram_unpin);
 
-static int drm_gem_vram_kmap_locked(struct drm_gem_vram_object *gbo,
-   struct iosys_map *map)
+/**
+ * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
+ *   space
+ * @gbo: The GEM VRAM object to map
+ * @map: Returns the kernel virtual address of the VRAM GEM object's backing
+ *   store.
+ *
+ * The vmap function pins a GEM VRAM object to its current location, either
+ * system or video memory, and maps its buffer into kernel address space.
+ * As pinned object cannot be relocated, you should avoid pinning objects
+ * permanently. Call drm_gem_vram_vunmap() with the returned address to
+ * unmap and unpin the GEM VRAM object.
+ *
+ * Returns:
+ * 0 on success, or a negative error code otherwise.
+ */
+int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct iosys_map *map)
 {
int ret;
 
+   dma_resv_assert_held(gbo->bo.base.resv);
+
if (gbo->vmap_use_count > 0)
goto out;
 
@@ -393,12 +410,23 @@ static int drm_gem_vram_kmap_locked(struct 
drm_gem_vram_object *gbo,
 
return 0;
 }
+EXPORT_SYMBOL(drm_gem_vram_vmap);
 
-static void drm_gem_vram_kunmap_locked(struct drm_gem_vram_object *gbo,
-  struct iosys_map *map)
+/**
+ * drm_gem_vram_vunmap() - Unmaps and unpins a GEM VRAM object
+ * @gbo: The GEM VRAM object to unmap
+ * @map: Kernel virtual address where the VRAM GEM object was mapped
+ *
+ * A call to drm_gem_vram_vunmap() unmaps and unpins a GEM VRAM buffer. See
+ * the documentation for drm_gem_vram_vmap() for more information.
+ */
+void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo,
+struct iosys_map *map)
 {
struct drm_device *dev = gbo->bo.base.dev;
 
+   dma_resv_assert_held(gbo->bo.base.resv);
+
if (drm_WARN_ON_ONCE(dev, !gbo->vmap_use_count))
return;
 
@@ -415,60 +443,6 @@ static void drm_gem_vram_kunmap_locked(struct 
drm_gem_vram_object *gbo,
 * from memory. See drm_gem_vram_bo_driver_move_notify().
 */
 }
-
-/**
- * drm_gem_vram_vmap() - Pins and maps a GEM VRAM object into kernel address
- *   space
- * @gbo: The GEM VRAM object to map
- * @map: Returns the kernel virtual address of the VRAM GEM object's backing
- *   store.
- *
- * The vmap function pins a GEM VRAM object to its current location, either
- * system or video memory, and maps its buffer into kernel address space.
- * As pinned object cannot be relocated, you should avoid pinning objects
- * permanently. Call drm_gem_vram_vunmap() with the returned address to
- * unmap and unpin the GEM VRAM object.
- *
- * Returns:
- * 0 on success, or a negative error code otherwise.
- */
-int drm_gem_vram_vmap(struct drm_gem_vram_object *gbo, struct iosys_map *map)
-{
-   int ret;
-
-   dma_resv_assert_held(gbo->bo.base.resv);
-
-   ret = drm_gem_vram_pin_locked(gbo, 0);
-   if (ret)
-   return ret;
-   ret = drm_gem_vram_kmap_locked(gbo, map);
-   if (ret)
-   goto err_drm_gem_vram_unpin_locked;
-
-   return 0;
-
-err_drm_gem_vram_unpin_locked:
-   drm_gem_vram_unpin_locked(gbo);
-   return ret;
-}
-EXPORT_SYMBOL(drm_gem_vram_vmap);
-
-/**
- * drm_gem_vram_vunmap() - Unmaps and unpins a GEM VRAM object
- * @gbo: The GEM VRAM object to unmap
- * @map: Kernel virtual address where the VRAM GEM object was mapped
- *
- * A call to drm_gem_vram_vunmap() unmaps and unpins a GEM VRAM buffer. See
- * the documentation for drm_gem_vram_vmap() for more information.
- */
-void drm_gem_vram_vunmap(struct drm_gem_vram_object *gbo,
-struct iosys_map *map)
-{
-   dma_resv_assert_held(gbo->bo.base.resv);
-
-   drm_gem_vram_kunmap_locked(gbo, map);
-   drm_gem_vram_unpin_locked(gbo);
-}
 EXPORT_SYMBOL(drm_gem_vram_vunmap);
 
 /**
-- 
2.43.2



[PATCH 09/13] drm/gem: Acquire reservation lock in drm_gem_{pin/unpin}()

2024-02-27 Thread Thomas Zimmermann
Acquire the buffer object's reservation lock in drm_gem_pin() and
remove locking the drivers' GEM callbacks where necessary. Same for
unpin().

DRM drivers and memory managers modified by this patch will now have
correct dma-buf locking semantics: the caller is responsible for
holding the reservation lock when calling the pin or unpin callback.

DRM drivers and memory managers that are not modified will now be
protected against concurent invocation of their pin and unpin callbacks.

PRIME does not implement struct dma_buf_ops.pin, which requires
the caller to hold the reservation lock. It does implement struct
dma_buf_ops.attach, which requires to callee to acquire the
reservation lock. The PRIME code uses drm_gem_pin(), so locks
are now taken as specified. Same for unpin and detach.

The patch harmonizes GEM pin and unpin to have non-interruptible
reservation locking across all drivers, as is already the case for
vmap and vunmap. This affects gem-shmem, gem-vram, loongson, qxl and
radeon.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_gem.c   | 22 --
 drivers/gpu/drm/drm_gem_vram_helper.c   | 15 +--
 drivers/gpu/drm/drm_internal.h  |  2 ++
 drivers/gpu/drm/loongson/lsdc_gem.c | 13 ++---
 drivers/gpu/drm/msm/msm_gem_prime.c |  4 
 drivers/gpu/drm/nouveau/nouveau_prime.c | 11 ---
 drivers/gpu/drm/qxl/qxl_prime.c | 14 +-
 drivers/gpu/drm/radeon/radeon_prime.c   | 11 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c | 25 ++---
 include/drm/drm_gem_shmem_helper.h  | 11 +--
 10 files changed, 33 insertions(+), 95 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem.c b/drivers/gpu/drm/drm_gem.c
index 44a948b80ee14..e0f80c6a7096f 100644
--- a/drivers/gpu/drm/drm_gem.c
+++ b/drivers/gpu/drm/drm_gem.c
@@ -1161,7 +1161,7 @@ void drm_gem_print_info(struct drm_printer *p, unsigned 
int indent,
obj->funcs->print_info(p, indent, obj);
 }
 
-int drm_gem_pin(struct drm_gem_object *obj)
+int drm_gem_pin_locked(struct drm_gem_object *obj)
 {
if (obj->funcs->pin)
return obj->funcs->pin(obj);
@@ -1169,12 +1169,30 @@ int drm_gem_pin(struct drm_gem_object *obj)
return 0;
 }
 
-void drm_gem_unpin(struct drm_gem_object *obj)
+void drm_gem_unpin_locked(struct drm_gem_object *obj)
 {
if (obj->funcs->unpin)
obj->funcs->unpin(obj);
 }
 
+int drm_gem_pin(struct drm_gem_object *obj)
+{
+   int ret;
+
+   dma_resv_lock(obj->resv, NULL);
+   ret = drm_gem_pin_locked(obj);
+   dma_resv_unlock(obj->resv);
+
+   return ret;
+}
+
+void drm_gem_unpin(struct drm_gem_object *obj)
+{
+   dma_resv_lock(obj->resv, NULL);
+   drm_gem_unpin_locked(obj);
+   dma_resv_unlock(obj->resv);
+}
+
 int drm_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map)
 {
int ret;
diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
b/drivers/gpu/drm/drm_gem_vram_helper.c
index 15029d89badf8..5a16b3e0a4134 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -774,11 +774,6 @@ EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_cleanup_fb);
 static int drm_gem_vram_object_pin(struct drm_gem_object *gem)
 {
struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
-   int ret;
-
-   ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
-   if (ret)
-   return ret;
 
/*
 * Fbdev console emulation is the use case of these PRIME
@@ -789,10 +784,7 @@ static int drm_gem_vram_object_pin(struct drm_gem_object 
*gem)
 * the buffer to be pinned to VRAM, implement a callback that
 * sets the flags accordingly.
 */
-   ret = drm_gem_vram_pin_locked(gbo, 0);
-   ttm_bo_unreserve(&gbo->bo);
-
-   return ret;
+   return drm_gem_vram_pin_locked(gbo, 0);
 }
 
 /**
@@ -803,13 +795,8 @@ static int drm_gem_vram_object_pin(struct drm_gem_object 
*gem)
 static void drm_gem_vram_object_unpin(struct drm_gem_object *gem)
 {
struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
-   int ret;
 
-   ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
-   if (ret)
-   return;
drm_gem_vram_unpin_locked(gbo);
-   ttm_bo_unreserve(&gbo->bo);
 }
 
 /**
diff --git a/drivers/gpu/drm/drm_internal.h b/drivers/gpu/drm/drm_internal.h
index 8e4faf0a28e6c..40b2d3a274d6c 100644
--- a/drivers/gpu/drm/drm_internal.h
+++ b/drivers/gpu/drm/drm_internal.h
@@ -170,6 +170,8 @@ void drm_gem_release(struct drm_device *dev, struct 
drm_file *file_private);
 void drm_gem_print_info(struct drm_printer *p, unsigned int indent,
const struct drm_gem_object *obj);
 
+int drm_gem_pin_locked(struct drm_gem_object *obj);
+void drm_gem_unpin_locked(struct drm_gem_object *obj);
 int drm_gem

[PATCH 08/13] drm/qxl: Acquire reservation lock in GEM pin/unpin callbacks

2024-02-27 Thread Thomas Zimmermann
Acquire the reservation lock directly in GEM pin callback. Same for
unpin. Prepares for further changes.

Dma-buf locking semantics require callers to hold the buffer's
reservation lock when invoking the pin and unpin callbacks. Prepare
qxl accordingly by pushing locking out of the implementation. A
follow-up patch will fix locking for all GEM code at once.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/qxl/qxl_prime.c | 16 ++--
 1 file changed, 14 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_prime.c b/drivers/gpu/drm/qxl/qxl_prime.c
index 9169c26357d36..f2646603e12eb 100644
--- a/drivers/gpu/drm/qxl/qxl_prime.c
+++ b/drivers/gpu/drm/qxl/qxl_prime.c
@@ -31,15 +31,27 @@
 int qxl_gem_prime_pin(struct drm_gem_object *obj)
 {
struct qxl_bo *bo = gem_to_qxl_bo(obj);
+   int r;
 
-   return qxl_bo_pin(bo);
+   r = qxl_bo_reserve(bo);
+   if (r)
+   return r;
+   r = qxl_bo_pin_locked(bo);
+   qxl_bo_unreserve(bo);
+
+   return r;
 }
 
 void qxl_gem_prime_unpin(struct drm_gem_object *obj)
 {
struct qxl_bo *bo = gem_to_qxl_bo(obj);
+   int r;
 
-   qxl_bo_unpin(bo);
+   r = qxl_bo_reserve(bo);
+   if (r)
+   return;
+   qxl_bo_unpin_locked(bo);
+   qxl_bo_unreserve(bo);
 }
 
 struct sg_table *qxl_gem_prime_get_sg_table(struct drm_gem_object *obj)
-- 
2.43.2



[PATCH 10/13] drm/fbdev-generic: Fix locking with drm_client_buffer_vmap_local()

2024-02-27 Thread Thomas Zimmermann
Temporarily lock the fbdev buffer object during updates to prevent
memory managers from evicting/moving the buffer. Moving a buffer
object while update its content results in undefined behaviour.

Fbdev-generic updates its buffer object from a shadow buffer. Gem-shmem
and gem-dma helpers do not move buffer objects, so they are safe to be
used with fbdev-generic. Gem-vram and qxl are based on TTM, but pin
buffer objects are part of the vmap operation. So both are also safe
to be used with fbdev-generic.

Amdgpu and nouveau do not pin or lock the buffer object during an
update. Their TTM-based memory management could move the buffer object
while the update is ongoing.

The new vmap_local and vunmap_local helpers hold the buffer object's
reservation lock during the buffer update. This prevents moving the
buffer object on all memory managers.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_client.c| 68 +
 drivers/gpu/drm/drm_fbdev_generic.c |  4 +-
 drivers/gpu/drm/drm_gem.c   | 12 +
 include/drm/drm_client.h| 10 +
 include/drm/drm_gem.h   |  3 ++
 5 files changed, 87 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 9403b3f576f7b..2cc81831236b5 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -304,6 +304,66 @@ drm_client_buffer_create(struct drm_client_dev *client, 
u32 width, u32 height,
return ERR_PTR(ret);
 }
 
+/**
+ * drm_client_buffer_vmap_local - Map DRM client buffer into address space
+ * @buffer: DRM client buffer
+ * @map_copy: Returns the mapped memory's address
+ *
+ * This function maps a client buffer into kernel address space. If the
+ * buffer is already mapped, it returns the existing mapping's address.
+ *
+ * Client buffer mappings are not ref'counted. Each call to
+ * drm_client_buffer_vmap_local() should be closely followed by a call to
+ * drm_client_buffer_vunmap_local(). See drm_client_buffer_vmap() for
+ * long-term mappings.
+ *
+ * The returned address is a copy of the internal value. In contrast to
+ * other vmap interfaces, you don't need it for the client's vunmap
+ * function. So you can modify it at will during blit and draw operations.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise.
+ */
+int drm_client_buffer_vmap_local(struct drm_client_buffer *buffer,
+struct iosys_map *map_copy)
+{
+   struct drm_gem_object *gem = buffer->gem;
+   struct iosys_map *map = &buffer->map;
+   int ret;
+
+   drm_gem_lock(gem);
+
+   ret = drm_gem_vmap(gem, map);
+   if (ret)
+   goto err_drm_gem_vmap_unlocked;
+   *map_copy = *map;
+
+   return 0;
+
+err_drm_gem_vmap_unlocked:
+   drm_gem_unlock(gem);
+   return 0;
+}
+EXPORT_SYMBOL(drm_client_buffer_vmap_local);
+
+/**
+ * drm_client_buffer_vunmap_local - Unmap DRM client buffer
+ * @buffer: DRM client buffer
+ *
+ * This function removes a client buffer's memory mapping established
+ * with drm_client_buffer_vunmap_local(). Calling this function is only
+ * required by clients that manage their buffer mappings by themselves.
+ */
+void drm_client_buffer_vunmap_local(struct drm_client_buffer *buffer)
+{
+   struct drm_gem_object *gem = buffer->gem;
+   struct iosys_map *map = &buffer->map;
+
+   drm_gem_vunmap(gem, map);
+   drm_gem_unlock(gem);
+}
+EXPORT_SYMBOL(drm_client_buffer_vunmap_local);
+
 /**
  * drm_client_buffer_vmap - Map DRM client buffer into address space
  * @buffer: DRM client buffer
@@ -331,14 +391,6 @@ drm_client_buffer_vmap(struct drm_client_buffer *buffer,
struct iosys_map *map = &buffer->map;
int ret;
 
-   /*
-* FIXME: The dependency on GEM here isn't required, we could
-* convert the driver handle to a dma-buf instead and use the
-* backend-agnostic dma-buf vmap support instead. This would
-* require that the handle2fd prime ioctl is reworked to pull the
-* fd_install step out of the driver backend hooks, to make that
-* final step optional for internal users.
-*/
ret = drm_gem_vmap_unlocked(buffer->gem, map);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
b/drivers/gpu/drm/drm_fbdev_generic.c
index d647d89764cb9..be357f926faec 100644
--- a/drivers/gpu/drm/drm_fbdev_generic.c
+++ b/drivers/gpu/drm/drm_fbdev_generic.c
@@ -197,14 +197,14 @@ static int drm_fbdev_generic_damage_blit(struct 
drm_fb_helper *fb_helper,
 */
mutex_lock(&fb_helper->lock);
 
-   ret = drm_client_buffer_vmap(buffer, &map);
+   ret = drm_client_buffer_vmap_local(buffer, &map);
if (ret)
goto out;
 
dst = map;
drm_fbdev_gener

[PATCH 11/13] drm/client: Pin vmap'ed GEM buffers

2024-02-27 Thread Thomas Zimmermann
The function drm_client_buffer_vmap() establishes a long-term mapping
of the client's buffer object into the kernel address space. Make sure
that buffer does not move by pinning it to its current location. Same
for vunmap with unpin.

The only caller of drm_client_buffer_vmap() is fbdev-dma, which uses
gem-dma. As DMA-backed GEM buffers do not move, this change is for
correctness with little impact in practice.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_client.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_client.c b/drivers/gpu/drm/drm_client.c
index 2cc81831236b5..77fe217aeaf36 100644
--- a/drivers/gpu/drm/drm_client.c
+++ b/drivers/gpu/drm/drm_client.c
@@ -388,16 +388,30 @@ int
 drm_client_buffer_vmap(struct drm_client_buffer *buffer,
   struct iosys_map *map_copy)
 {
+   struct drm_gem_object *gem = buffer->gem;
struct iosys_map *map = &buffer->map;
int ret;
 
-   ret = drm_gem_vmap_unlocked(buffer->gem, map);
+   drm_gem_lock(gem);
+
+   ret = drm_gem_pin_locked(gem);
if (ret)
-   return ret;
+   goto err_drm_gem_pin_locked;
+   ret = drm_gem_vmap(gem, map);
+   if (ret)
+   goto err_drm_gem_vmap;
+
+   drm_gem_unlock(gem);
 
*map_copy = *map;
 
return 0;
+
+err_drm_gem_vmap:
+   drm_gem_unpin_locked(buffer->gem);
+err_drm_gem_pin_locked:
+   drm_gem_unlock(gem);
+   return ret;
 }
 EXPORT_SYMBOL(drm_client_buffer_vmap);
 
@@ -411,9 +425,13 @@ EXPORT_SYMBOL(drm_client_buffer_vmap);
  */
 void drm_client_buffer_vunmap(struct drm_client_buffer *buffer)
 {
+   struct drm_gem_object *gem = buffer->gem;
struct iosys_map *map = &buffer->map;
 
-   drm_gem_vunmap_unlocked(buffer->gem, map);
+   drm_gem_lock(gem);
+   drm_gem_vunmap(gem, map);
+   drm_gem_unpin_locked(gem);
+   drm_gem_unlock(gem);
 }
 EXPORT_SYMBOL(drm_client_buffer_vunmap);
 
-- 
2.43.2



[PATCH 07/13] drm/qxl: Provide qxl_bo_{pin,unpin}_locked()

2024-02-27 Thread Thomas Zimmermann
Rename __qxl_bo_pin() to qxl_bo_pin_locked() and update all callers.
The function will be helpful for implementing the GEM pin callback
with correct semantics. Same for __qxl_bo_unpin().

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/qxl/qxl_object.c | 25 +
 drivers/gpu/drm/qxl/qxl_object.h |  2 ++
 2 files changed, 15 insertions(+), 12 deletions(-)

diff --git a/drivers/gpu/drm/qxl/qxl_object.c b/drivers/gpu/drm/qxl/qxl_object.c
index 1e46b0a6e4787..39218e979a807 100644
--- a/drivers/gpu/drm/qxl/qxl_object.c
+++ b/drivers/gpu/drm/qxl/qxl_object.c
@@ -29,9 +29,6 @@
 #include "qxl_drv.h"
 #include "qxl_object.h"
 
-static int __qxl_bo_pin(struct qxl_bo *bo);
-static void __qxl_bo_unpin(struct qxl_bo *bo);
-
 static void qxl_ttm_bo_destroy(struct ttm_buffer_object *tbo)
 {
struct qxl_bo *bo;
@@ -167,13 +164,13 @@ int qxl_bo_vmap_locked(struct qxl_bo *bo, struct 
iosys_map *map)
goto out;
}
 
-   r = __qxl_bo_pin(bo);
+   r = qxl_bo_pin_locked(bo);
if (r)
return r;
 
r = ttm_bo_vmap(&bo->tbo, &bo->map);
if (r) {
-   __qxl_bo_unpin(bo);
+   qxl_bo_unpin_locked(bo);
return r;
}
bo->map_count = 1;
@@ -246,7 +243,7 @@ void qxl_bo_vunmap_locked(struct qxl_bo *bo)
return;
bo->kptr = NULL;
ttm_bo_vunmap(&bo->tbo, &bo->map);
-   __qxl_bo_unpin(bo);
+   qxl_bo_unpin_locked(bo);
 }
 
 int qxl_bo_vunmap(struct qxl_bo *bo)
@@ -290,12 +287,14 @@ struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo)
return bo;
 }
 
-static int __qxl_bo_pin(struct qxl_bo *bo)
+int qxl_bo_pin_locked(struct qxl_bo *bo)
 {
struct ttm_operation_ctx ctx = { false, false };
struct drm_device *ddev = bo->tbo.base.dev;
int r;
 
+   dma_resv_assert_held(bo->tbo.base.resv);
+
if (bo->tbo.pin_count) {
ttm_bo_pin(&bo->tbo);
return 0;
@@ -309,14 +308,16 @@ static int __qxl_bo_pin(struct qxl_bo *bo)
return r;
 }
 
-static void __qxl_bo_unpin(struct qxl_bo *bo)
+void qxl_bo_unpin_locked(struct qxl_bo *bo)
 {
+   dma_resv_assert_held(bo->tbo.base.resv);
+
ttm_bo_unpin(&bo->tbo);
 }
 
 /*
  * Reserve the BO before pinning the object.  If the BO was reserved
- * beforehand, use the internal version directly __qxl_bo_pin.
+ * beforehand, use the internal version directly qxl_bo_pin_locked.
  *
  */
 int qxl_bo_pin(struct qxl_bo *bo)
@@ -327,14 +328,14 @@ int qxl_bo_pin(struct qxl_bo *bo)
if (r)
return r;
 
-   r = __qxl_bo_pin(bo);
+   r = qxl_bo_pin_locked(bo);
qxl_bo_unreserve(bo);
return r;
 }
 
 /*
  * Reserve the BO before pinning the object.  If the BO was reserved
- * beforehand, use the internal version directly __qxl_bo_unpin.
+ * beforehand, use the internal version directly qxl_bo_unpin_locked.
  *
  */
 int qxl_bo_unpin(struct qxl_bo *bo)
@@ -345,7 +346,7 @@ int qxl_bo_unpin(struct qxl_bo *bo)
if (r)
return r;
 
-   __qxl_bo_unpin(bo);
+   qxl_bo_unpin_locked(bo);
qxl_bo_unreserve(bo);
return 0;
 }
diff --git a/drivers/gpu/drm/qxl/qxl_object.h b/drivers/gpu/drm/qxl/qxl_object.h
index 53392cb90eecf..1cf5bc7591016 100644
--- a/drivers/gpu/drm/qxl/qxl_object.h
+++ b/drivers/gpu/drm/qxl/qxl_object.h
@@ -67,6 +67,8 @@ void *qxl_bo_kmap_atomic_page(struct qxl_device *qdev, struct 
qxl_bo *bo, int pa
 void qxl_bo_kunmap_atomic_page(struct qxl_device *qdev, struct qxl_bo *bo, 
void *map);
 extern struct qxl_bo *qxl_bo_ref(struct qxl_bo *bo);
 extern void qxl_bo_unref(struct qxl_bo **bo);
+extern int qxl_bo_pin_locked(struct qxl_bo *bo);
+extern void qxl_bo_unpin_locked(struct qxl_bo *bo);
 extern int qxl_bo_pin(struct qxl_bo *bo);
 extern int qxl_bo_unpin(struct qxl_bo *bo);
 extern void qxl_ttm_placement_from_domain(struct qxl_bo *qbo, u32 domain);
-- 
2.43.2



[PATCH 04/13] drm/msm: Acquire reservation lock in GEM pin/unpin callback

2024-02-27 Thread Thomas Zimmermann
Export msm_gem_pin_pages_locked() and acquire the reservation lock
directly in GEM pin callback. Same for unpin. Prepares for further
changes.

Dma-buf locking semantics require callers to hold the buffer's
reservation lock when invoking the pin and unpin callbacks. Prepare
msm accordingly by pushing locking out of the implementation. A
follow-up patch will fix locking for all GEM code at once.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/msm/msm_gem.c   | 12 ++--
 drivers/gpu/drm/msm/msm_gem.h   |  4 ++--
 drivers/gpu/drm/msm/msm_gem_prime.c | 24 +++-
 3 files changed, 27 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index bb729353d3a8d..a5c6498a43f06 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -257,24 +257,24 @@ static void pin_obj_locked(struct drm_gem_object *obj)
mutex_unlock(&priv->lru.lock);
 }
 
-struct page **msm_gem_pin_pages(struct drm_gem_object *obj)
+struct page **msm_gem_pin_pages_locked(struct drm_gem_object *obj)
 {
struct page **p;
 
-   msm_gem_lock(obj);
+   msm_gem_assert_locked(obj);
+
p = msm_gem_get_pages_locked(obj, MSM_MADV_WILLNEED);
if (!IS_ERR(p))
pin_obj_locked(obj);
-   msm_gem_unlock(obj);
 
return p;
 }
 
-void msm_gem_unpin_pages(struct drm_gem_object *obj)
+void msm_gem_unpin_pages_locked(struct drm_gem_object *obj)
 {
-   msm_gem_lock(obj);
+   msm_gem_assert_locked(obj);
+
msm_gem_unpin_locked(obj);
-   msm_gem_unlock(obj);
 }
 
 static pgprot_t msm_gem_pgprot(struct msm_gem_object *msm_obj, pgprot_t prot)
diff --git a/drivers/gpu/drm/msm/msm_gem.h b/drivers/gpu/drm/msm/msm_gem.h
index 8d414b072c29d..85f0257e83dab 100644
--- a/drivers/gpu/drm/msm/msm_gem.h
+++ b/drivers/gpu/drm/msm/msm_gem.h
@@ -140,8 +140,8 @@ int msm_gem_get_and_pin_iova(struct drm_gem_object *obj,
 void msm_gem_unpin_iova(struct drm_gem_object *obj,
struct msm_gem_address_space *aspace);
 void msm_gem_pin_obj_locked(struct drm_gem_object *obj);
-struct page **msm_gem_pin_pages(struct drm_gem_object *obj);
-void msm_gem_unpin_pages(struct drm_gem_object *obj);
+struct page **msm_gem_pin_pages_locked(struct drm_gem_object *obj);
+void msm_gem_unpin_pages_locked(struct drm_gem_object *obj);
 int msm_gem_dumb_create(struct drm_file *file, struct drm_device *dev,
struct drm_mode_create_dumb *args);
 int msm_gem_dumb_map_offset(struct drm_file *file, struct drm_device *dev,
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c 
b/drivers/gpu/drm/msm/msm_gem_prime.c
index 0915f3b68752e..0d22df53ab98a 100644
--- a/drivers/gpu/drm/msm/msm_gem_prime.c
+++ b/drivers/gpu/drm/msm/msm_gem_prime.c
@@ -47,13 +47,27 @@ struct drm_gem_object *msm_gem_prime_import_sg_table(struct 
drm_device *dev,
 
 int msm_gem_prime_pin(struct drm_gem_object *obj)
 {
-   if (!obj->import_attach)
-   msm_gem_pin_pages(obj);
-   return 0;
+   struct page **pages;
+   int ret = 0;
+
+   if (obj->import_attach)
+   return 0;
+
+   msm_gem_lock(obj);
+   pages = msm_gem_pin_pages_locked(obj);
+   if (IS_ERR(pages))
+   ret = PTR_ERR(pages);
+   msm_gem_unlock(obj);
+
+   return ret;
 }
 
 void msm_gem_prime_unpin(struct drm_gem_object *obj)
 {
-   if (!obj->import_attach)
-   msm_gem_unpin_pages(obj);
+   if (obj->import_attach)
+   return;
+
+   msm_gem_lock(obj);
+   msm_gem_unpin_pages_locked(obj);
+   msm_gem_unlock(obj);
 }
-- 
2.43.2



[PATCH 06/13] drm/nouveau: Acquire reservation lock in GEM pin/unpin callbacks

2024-02-27 Thread Thomas Zimmermann
Acquire the reservation lock directly in GEM pin callback. Same for
unpin. Prepares for further changes.

Dma-buf locking semantics require callers to hold the buffer's
reservation lock when invoking the pin and unpin callbacks. Prepare
nouveau accordingly by pushing locking out of the implementation. A
follow-up patch will fix locking for all GEM code at once.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/nouveau/nouveau_prime.c | 19 +++
 1 file changed, 15 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_prime.c 
b/drivers/gpu/drm/nouveau/nouveau_prime.c
index 1b2ff0c40fc1c..774f9bd031102 100644
--- a/drivers/gpu/drm/nouveau/nouveau_prime.c
+++ b/drivers/gpu/drm/nouveau/nouveau_prime.c
@@ -86,21 +86,32 @@ struct drm_gem_object 
*nouveau_gem_prime_import_sg_table(struct drm_device *dev,
 int nouveau_gem_prime_pin(struct drm_gem_object *obj)
 {
struct nouveau_bo *nvbo = nouveau_gem_object(obj);
+   struct ttm_buffer_object *bo = &nvbo->bo;
int ret;
 
-   /* pin buffer into GTT */
-   ret = nouveau_bo_pin(nvbo, NOUVEAU_GEM_DOMAIN_GART, false);
+   ret = ttm_bo_reserve(bo, false, false, NULL);
if (ret)
return -EINVAL;
+   /* pin buffer into GTT */
+   ret = nouveau_bo_pin_locked(nvbo, NOUVEAU_GEM_DOMAIN_GART, false);
+   if (ret)
+   ret = -EINVAL;
+   ttm_bo_unreserve(bo);
 
-   return 0;
+   return ret;
 }
 
 void nouveau_gem_prime_unpin(struct drm_gem_object *obj)
 {
struct nouveau_bo *nvbo = nouveau_gem_object(obj);
+   struct ttm_buffer_object *bo = &nvbo->bo;
+   int ret;
 
-   nouveau_bo_unpin(nvbo);
+   ret = ttm_bo_reserve(bo, false, false, NULL);
+   if (ret)
+   return;
+   nouveau_bo_unpin_locked(nvbo);
+   ttm_bo_unreserve(bo);
 }
 
 struct dma_buf *nouveau_gem_prime_export(struct drm_gem_object *gobj,
-- 
2.43.2



[PATCH 05/13] drm/nouveau: Provide nouveau_bo_{pin,unpin}_locked()

2024-02-27 Thread Thomas Zimmermann
Implement pinning without locking in nouveau_bo_pin_locked(). Keep
nouveau_bo_pin() for acquiring the buffer object's reservation lock.
The new helper will be useful for implementing the GEM pin callback
with correct semantics. Same for unpin.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/nouveau/nouveau_bo.c | 43 +++-
 drivers/gpu/drm/nouveau/nouveau_bo.h |  2 ++
 2 files changed, 32 insertions(+), 13 deletions(-)

diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.c 
b/drivers/gpu/drm/nouveau/nouveau_bo.c
index 56dcd25db1ce2..4a7c002a325a4 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.c
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.c
@@ -467,17 +467,14 @@ nouveau_bo_placement_set(struct nouveau_bo *nvbo, 
uint32_t domain,
set_placement_range(nvbo, domain);
 }
 
-int
-nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t domain, bool contig)
+int nouveau_bo_pin_locked(struct nouveau_bo *nvbo, uint32_t domain, bool 
contig)
 {
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct ttm_buffer_object *bo = &nvbo->bo;
bool force = false, evict = false;
-   int ret;
+   int ret = 0;
 
-   ret = ttm_bo_reserve(bo, false, false, NULL);
-   if (ret)
-   return ret;
+   dma_resv_assert_held(bo->base.resv);
 
if (drm->client.device.info.family >= NV_DEVICE_INFO_V0_TESLA &&
domain == NOUVEAU_GEM_DOMAIN_VRAM && contig) {
@@ -540,20 +537,15 @@ nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t domain, 
bool contig)
 out:
if (force && ret)
nvbo->contig = false;
-   ttm_bo_unreserve(bo);
return ret;
 }
 
-int
-nouveau_bo_unpin(struct nouveau_bo *nvbo)
+void nouveau_bo_unpin_locked(struct nouveau_bo *nvbo)
 {
struct nouveau_drm *drm = nouveau_bdev(nvbo->bo.bdev);
struct ttm_buffer_object *bo = &nvbo->bo;
-   int ret;
 
-   ret = ttm_bo_reserve(bo, false, false, NULL);
-   if (ret)
-   return ret;
+   dma_resv_assert_held(bo->base.resv);
 
ttm_bo_unpin(&nvbo->bo);
if (!nvbo->bo.pin_count) {
@@ -568,8 +560,33 @@ nouveau_bo_unpin(struct nouveau_bo *nvbo)
break;
}
}
+}
+
+int nouveau_bo_pin(struct nouveau_bo *nvbo, uint32_t domain, bool contig)
+{
+   struct ttm_buffer_object *bo = &nvbo->bo;
+   int ret;
 
+   ret = ttm_bo_reserve(bo, false, false, NULL);
+   if (ret)
+   return ret;
+   ret = nouveau_bo_pin_locked(nvbo, domain, contig);
+   ttm_bo_unreserve(bo);
+
+   return ret;
+}
+
+int nouveau_bo_unpin(struct nouveau_bo *nvbo)
+{
+   struct ttm_buffer_object *bo = &nvbo->bo;
+   int ret;
+
+   ret = ttm_bo_reserve(bo, false, false, NULL);
+   if (ret)
+   return ret;
+   nouveau_bo_unpin_locked(nvbo);
ttm_bo_unreserve(bo);
+
return 0;
 }
 
diff --git a/drivers/gpu/drm/nouveau/nouveau_bo.h 
b/drivers/gpu/drm/nouveau/nouveau_bo.h
index e9dfab6a81560..4e891752c2551 100644
--- a/drivers/gpu/drm/nouveau/nouveau_bo.h
+++ b/drivers/gpu/drm/nouveau/nouveau_bo.h
@@ -85,6 +85,8 @@ int  nouveau_bo_new(struct nouveau_cli *, u64 size, int 
align, u32 domain,
u32 tile_mode, u32 tile_flags, struct sg_table *sg,
struct dma_resv *robj,
struct nouveau_bo **);
+int  nouveau_bo_pin_locked(struct nouveau_bo *nvbo, uint32_t domain, bool 
contig);
+void nouveau_bo_unpin_locked(struct nouveau_bo *nvbo);
 int  nouveau_bo_pin(struct nouveau_bo *, u32 flags, bool contig);
 int  nouveau_bo_unpin(struct nouveau_bo *);
 int  nouveau_bo_map(struct nouveau_bo *);
-- 
2.43.2



[PATCH 03/13] drm/msm: Provide msm_gem_get_pages_locked()

2024-02-27 Thread Thomas Zimmermann
Rename msm_gem_pin_pages_locked() to msm_gem_get_pages_locked(). The
function doesn't pin any pages, but only acquires them. Renaming the
function makes the old name available.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/msm/msm_gem.c | 8 
 1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 175ee4ab8a6f7..bb729353d3a8d 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -219,7 +219,7 @@ static void put_pages(struct drm_gem_object *obj)
}
 }
 
-static struct page **msm_gem_pin_pages_locked(struct drm_gem_object *obj,
+static struct page **msm_gem_get_pages_locked(struct drm_gem_object *obj,
  unsigned madv)
 {
struct msm_gem_object *msm_obj = to_msm_bo(obj);
@@ -262,7 +262,7 @@ struct page **msm_gem_pin_pages(struct drm_gem_object *obj)
struct page **p;
 
msm_gem_lock(obj);
-   p = msm_gem_pin_pages_locked(obj, MSM_MADV_WILLNEED);
+   p = msm_gem_get_pages_locked(obj, MSM_MADV_WILLNEED);
if (!IS_ERR(p))
pin_obj_locked(obj);
msm_gem_unlock(obj);
@@ -489,7 +489,7 @@ int msm_gem_pin_vma_locked(struct drm_gem_object *obj, 
struct msm_gem_vma *vma)
 
msm_gem_assert_locked(obj);
 
-   pages = msm_gem_pin_pages_locked(obj, MSM_MADV_WILLNEED);
+   pages = msm_gem_get_pages_locked(obj, MSM_MADV_WILLNEED);
if (IS_ERR(pages))
return PTR_ERR(pages);
 
@@ -703,7 +703,7 @@ static void *get_vaddr(struct drm_gem_object *obj, unsigned 
madv)
if (obj->import_attach)
return ERR_PTR(-ENODEV);
 
-   pages = msm_gem_pin_pages_locked(obj, madv);
+   pages = msm_gem_get_pages_locked(obj, madv);
if (IS_ERR(pages))
return ERR_CAST(pages);
 
-- 
2.43.2



[PATCH 02/13] drm/gem-vram: Acquire reservation lock in GEM pin/unpin callbacks

2024-02-27 Thread Thomas Zimmermann
Acquire the reservation lock directly in GEM pin callback. Same for
unpin. Prepares for further changes.

Dma-buf locking semantics require callers to hold the buffer's
reservation lock when invoking the pin and unpin callbacks. Prepare
gem-vram accordingly by pushing locking out of the implementation.
A follow-up patch will fix locking for all GEM code at once.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_gem_vram_helper.c | 24 +---
 1 file changed, 21 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_vram_helper.c 
b/drivers/gpu/drm/drm_gem_vram_helper.c
index 75f2eaf0d5b61..15029d89badf8 100644
--- a/drivers/gpu/drm/drm_gem_vram_helper.c
+++ b/drivers/gpu/drm/drm_gem_vram_helper.c
@@ -283,6 +283,8 @@ static int drm_gem_vram_pin_locked(struct 
drm_gem_vram_object *gbo,
struct ttm_operation_ctx ctx = { false, false };
int ret;
 
+   dma_resv_assert_held(gbo->bo.base.resv);
+
if (gbo->bo.pin_count)
goto out;
 
@@ -338,6 +340,8 @@ EXPORT_SYMBOL(drm_gem_vram_pin);
 
 static void drm_gem_vram_unpin_locked(struct drm_gem_vram_object *gbo)
 {
+   dma_resv_assert_held(gbo->bo.base.resv);
+
ttm_bo_unpin(&gbo->bo);
 }
 
@@ -770,8 +774,14 @@ EXPORT_SYMBOL(drm_gem_vram_simple_display_pipe_cleanup_fb);
 static int drm_gem_vram_object_pin(struct drm_gem_object *gem)
 {
struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
+   int ret;
 
-   /* Fbdev console emulation is the use case of these PRIME
+   ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
+   if (ret)
+   return ret;
+
+   /*
+* Fbdev console emulation is the use case of these PRIME
 * helpers. This may involve updating a hardware buffer from
 * a shadow FB. We pin the buffer to it's current location
 * (either video RAM or system memory) to prevent it from
@@ -779,7 +789,10 @@ static int drm_gem_vram_object_pin(struct drm_gem_object 
*gem)
 * the buffer to be pinned to VRAM, implement a callback that
 * sets the flags accordingly.
 */
-   return drm_gem_vram_pin(gbo, 0);
+   ret = drm_gem_vram_pin_locked(gbo, 0);
+   ttm_bo_unreserve(&gbo->bo);
+
+   return ret;
 }
 
 /**
@@ -790,8 +803,13 @@ static int drm_gem_vram_object_pin(struct drm_gem_object 
*gem)
 static void drm_gem_vram_object_unpin(struct drm_gem_object *gem)
 {
struct drm_gem_vram_object *gbo = drm_gem_vram_of_gem(gem);
+   int ret;
 
-   drm_gem_vram_unpin(gbo);
+   ret = ttm_bo_reserve(&gbo->bo, true, false, NULL);
+   if (ret)
+   return;
+   drm_gem_vram_unpin_locked(gbo);
+   ttm_bo_unreserve(&gbo->bo);
 }
 
 /**
-- 
2.43.2



[PATCH 01/13] drm/gem-shmem: Acquire reservation lock in GEM pin/unpin callbacks

2024-02-27 Thread Thomas Zimmermann
Export drm_gem_shmem_pin_locked() and acquire the reservation lock
directly in GEM pin callback. Same for unpin. Prepares for further
changes.

Dma-buf locking semantics require callers to hold the buffer's
reservation lock when invoking the pin and unpin callbacks. Prepare
gem-shmem accordingly by pushing locking out of the implementation.
A follow-up patch will fix locking for all GEM code at once.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_gem_shmem_helper.c |  6 --
 include/drm/drm_gem_shmem_helper.h | 16 ++--
 2 files changed, 18 insertions(+), 4 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_shmem_helper.c 
b/drivers/gpu/drm/drm_gem_shmem_helper.c
index e435f986cd135..0ac3dddb917f3 100644
--- a/drivers/gpu/drm/drm_gem_shmem_helper.c
+++ b/drivers/gpu/drm/drm_gem_shmem_helper.c
@@ -228,7 +228,7 @@ void drm_gem_shmem_put_pages(struct drm_gem_shmem_object 
*shmem)
 }
 EXPORT_SYMBOL(drm_gem_shmem_put_pages);
 
-static int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem)
+int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem)
 {
int ret;
 
@@ -238,13 +238,15 @@ static int drm_gem_shmem_pin_locked(struct 
drm_gem_shmem_object *shmem)
 
return ret;
 }
+EXPORT_SYMBOL(drm_gem_shmem_pin_locked);
 
-static void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem)
+void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem)
 {
dma_resv_assert_held(shmem->base.resv);
 
drm_gem_shmem_put_pages(shmem);
 }
+EXPORT_SYMBOL(drm_gem_shmem_unpin_locked);
 
 /**
  * drm_gem_shmem_pin - Pin backing pages for a shmem GEM object
diff --git a/include/drm/drm_gem_shmem_helper.h 
b/include/drm/drm_gem_shmem_helper.h
index bf0c31aa8fbe4..eb12aa9a8c556 100644
--- a/include/drm/drm_gem_shmem_helper.h
+++ b/include/drm/drm_gem_shmem_helper.h
@@ -108,6 +108,9 @@ void drm_gem_shmem_vunmap(struct drm_gem_shmem_object 
*shmem,
  struct iosys_map *map);
 int drm_gem_shmem_mmap(struct drm_gem_shmem_object *shmem, struct 
vm_area_struct *vma);
 
+int drm_gem_shmem_pin_locked(struct drm_gem_shmem_object *shmem);
+void drm_gem_shmem_unpin_locked(struct drm_gem_shmem_object *shmem);
+
 int drm_gem_shmem_madvise(struct drm_gem_shmem_object *shmem, int madv);
 
 static inline bool drm_gem_shmem_is_purgeable(struct drm_gem_shmem_object 
*shmem)
@@ -172,8 +175,15 @@ static inline void drm_gem_shmem_object_print_info(struct 
drm_printer *p, unsign
 static inline int drm_gem_shmem_object_pin(struct drm_gem_object *obj)
 {
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+   int ret;
+
+   ret = dma_resv_lock_interruptible(shmem->base.resv, NULL);
+   if (ret)
+   return ret;
+   ret = drm_gem_shmem_pin_locked(shmem);
+   dma_resv_unlock(shmem->base.resv);
 
-   return drm_gem_shmem_pin(shmem);
+   return ret;
 }
 
 /**
@@ -187,7 +197,9 @@ static inline void drm_gem_shmem_object_unpin(struct 
drm_gem_object *obj)
 {
struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
 
-   drm_gem_shmem_unpin(shmem);
+   dma_resv_lock(shmem->base.resv, NULL);
+   drm_gem_shmem_unpin_locked(shmem);
+   dma_resv_unlock(shmem->base.resv);
 }
 
 /**
-- 
2.43.2



[PATCH 00/13] drm: Fix reservation locking for pin/unpin and console

2024-02-27 Thread Thomas Zimmermann
Dma-buf locking semantics require the caller of pin and unpin to hold
the buffer's reservation lock. Fix DRM to adhere to the specs. This
enables to fix the locking in DRM's console emulation. Similar changes
for vmap and mmap have been posted at [1][2]

Most DRM drivers and memory managers acquire the buffer object's
reservation lock within their GEM pin and unpin callbacks. This
violates dma-buf locking semantics. We get away with it because PRIME
does not provide pin/unpin, but attach/detach, for which the locking
semantics is correct.

Patches 1 to 8 rework DRM GEM code in various implementations to
acquire the reservation lock when entering the pin and unpin callbacks.
This prepares them for the next patch. Drivers that are not affected
by these patches either don't acquire the reservation lock (amdgpu)
or don't need preparation (loongson).

Patch 9 moves reservation locking from the GEM pin/unpin callbacks
into drm_gem_pin() and drm_gem_unpin(). As PRIME uses these functions
internally it still gets the reservation lock.

With the updated GEM callbacks, the rest of the patchset fixes the
fbdev emulation's buffer locking. Fbdev emulation needs to keep its
GEM buffer object inplace while updating its content. This required
a implicit pinning and apparently amdgpu didn't do this at all.

Patch 10 introduces drm_client_buffer_vmap_local() and _vunmap_local().
The former function map a GEM buffer into the kernel's address space
with regular vmap operations, but keeps holding the reservation lock.
The _vunmap_local() helper undoes the vmap and releases the lock. The
updated GEM callbacks make this possible. Between the two calls, the
fbdev emulation can update the buffer content without have the buffer
moved or evicted. Update fbdev-generic to use vmap_local helpers,
which fix amdgpu. The idea of adding a "local vmap" has previously been
attempted at [3] in a different form.

Patch 11 adds implicit pinning to the DRM client's regular vmap
helper so that long-term vmap'ed buffers won't be evicted. This only
affects fbdev-dma, but GEM DMA helpers don't require pinning. So
there are no practical changes.

Patches 12 and 13 remove implicit pinning from the vmap and vunmap
operations in gem-vram and qxl. These pin operations are not supposed
to be part of vmap code, but were required to keep the buffers in place
for fbdev emulation. With the conversion o ffbdev-generic to to
vmap_local helpers, that code can finally be removed.

Tested with amdgpu, nouveau, radeon, simpledrm and vc4.

[1] https://patchwork.freedesktop.org/series/106371/
[2] https://patchwork.freedesktop.org/series/116001/
[3] https://patchwork.freedesktop.org/series/84732/

Thomas Zimmermann (13):
  drm/gem-shmem: Acquire reservation lock in GEM pin/unpin callbacks
  drm/gem-vram: Acquire reservation lock in GEM pin/unpin callbacks
  drm/msm: Provide msm_gem_get_pages_locked()
  drm/msm: Acquire reservation lock in GEM pin/unpin callback
  drm/nouveau: Provide nouveau_bo_{pin,unpin}_locked()
  drm/nouveau: Acquire reservation lock in GEM pin/unpin callbacks
  drm/qxl: Provide qxl_bo_{pin,unpin}_locked()
  drm/qxl: Acquire reservation lock in GEM pin/unpin callbacks
  drm/gem: Acquire reservation lock in drm_gem_{pin/unpin}()
  drm/fbdev-generic: Fix locking with drm_client_buffer_vmap_local()
  drm/client: Pin vmap'ed GEM buffers
  drm/gem-vram: Do not pin buffer objects for vmap
  drm/qxl: Do not pin buffer objects for vmap

 drivers/gpu/drm/drm_client.c|  92 ++---
 drivers/gpu/drm/drm_fbdev_generic.c |   4 +-
 drivers/gpu/drm/drm_gem.c   |  34 +++-
 drivers/gpu/drm/drm_gem_shmem_helper.c  |   6 +-
 drivers/gpu/drm/drm_gem_vram_helper.c   | 101 ++--
 drivers/gpu/drm/drm_internal.h  |   2 +
 drivers/gpu/drm/loongson/lsdc_gem.c |  13 +--
 drivers/gpu/drm/msm/msm_gem.c   |  20 ++---
 drivers/gpu/drm/msm/msm_gem.h   |   4 +-
 drivers/gpu/drm/msm/msm_gem_prime.c |  20 +++--
 drivers/gpu/drm/nouveau/nouveau_bo.c|  43 +++---
 drivers/gpu/drm/nouveau/nouveau_bo.h|   2 +
 drivers/gpu/drm/nouveau/nouveau_prime.c |   8 +-
 drivers/gpu/drm/qxl/qxl_object.c|  26 +++---
 drivers/gpu/drm/qxl/qxl_object.h|   2 +
 drivers/gpu/drm/qxl/qxl_prime.c |   4 +-
 drivers/gpu/drm/radeon/radeon_prime.c   |  11 ---
 drivers/gpu/drm/vmwgfx/vmwgfx_gem.c |  25 ++
 include/drm/drm_client.h|  10 +++
 include/drm/drm_gem.h   |   3 +
 include/drm/drm_gem_shmem_helper.h  |   7 +-
 21 files changed, 265 insertions(+), 172 deletions(-)


base-commit: 7291e2e67dff0ff573900266382c9c9248a7dea5
prerequisite-patch-id: bdfa0e6341b30cc9d7647172760b3473007c1216
prerequisite-patch-id: bc27ac702099f481890ae2c7c4a9c531f4a62d64
prerequisite-patch-id: f5d4bf16dc45334254527c2e31ee21ba4582761c
prerequisi

Re: [Freedreno] [PATCH v4 00/20] remove I2C_CLASS_DDC support

2023-11-23 Thread Thomas Zimmermann

Hi

Am 23.11.23 um 09:34 schrieb Heiner Kallweit:

On 23.11.2023 09:19, Thomas Zimmermann wrote:

Hi

Am 23.11.23 um 08:16 schrieb Heiner Kallweit:

On 23.11.2023 07:56, Thomas Zimmermann wrote:

Hi

Am 20.11.23 um 22:46 schrieb Heiner Kallweit:

After removal of the legacy EEPROM driver and I2C_CLASS_DDC support in
olpc_dcon there's no i2c client driver left supporting I2C_CLASS_DDC.
Class-based device auto-detection is a legacy mechanism and shouldn't
be used in new code. So we can remove this class completely now.

Preferably this series should be applied via the i2c tree.

v2:
- change tag in commit subject of patch 03
- add ack tags
v3:
- fix a compile error in patch 5
v4:
- more ack and review tags

Signed-off-by: Heiner Kallweit 


Acked-by: Thomas Zimmermann 

for the patches that don't already have my r-b.


This refers to which patches of the series?
Patches 8, 16, 18 are the remaining ones w/o A-b or R-b.


I've looked through the patchset. Feel free to add my a-b to patches 1 to 19; 
except for 2 and 17, which already have my r-b.

BTW I only received 19 patches. is there a patch 20/20?


Yes, see here:
https://patchwork.ozlabs.org/project/linux-i2c/patch/20231120214624.9378-21-hkallwe...@gmail.com/
If you're subscribed to linux-i2c or linux-kernel list you should have received 
it.


I see, I'm not on these lists. I don't have the authority to ack that 
final patch, but let me know if you want to merge anything through the 
DRM trees.


Best regards
Thomas




Best regards
Thomas




Best regards
Thomas


Thanks, Heiner



---

    drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c   |    1 -
    drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |    1 -
    drivers/gpu/drm/ast/ast_i2c.c |    1 -
    drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |    1 -
    drivers/gpu/drm/display/drm_dp_helper.c   |    1 -
    drivers/gpu/drm/display/drm_dp_mst_topology.c |    1 -
    drivers/gpu/drm/gma500/cdv_intel_dp.c |    1 -
    drivers/gpu/drm/gma500/intel_gmbus.c  |    1 -
    drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c    |    1 -
    drivers/gpu/drm/gma500/psb_intel_sdvo.c   |    1 -
    drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c   |    1 -
    drivers/gpu/drm/i915/display/intel_gmbus.c    |    1 -
    drivers/gpu/drm/i915/display/intel_sdvo.c |    1 -
    drivers/gpu/drm/loongson/lsdc_i2c.c   |    1 -
    drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c   |    1 -
    drivers/gpu/drm/mgag200/mgag200_i2c.c |    1 -
    drivers/gpu/drm/msm/hdmi/hdmi_i2c.c   |    1 -
    drivers/gpu/drm/radeon/radeon_i2c.c   |    1 -
    drivers/gpu/drm/rockchip/inno_hdmi.c  |    1 -
    drivers/gpu/drm/rockchip/rk3066_hdmi.c    |    1 -
    drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c    |    1 -
    drivers/video/fbdev/core/fb_ddc.c |    1 -
    drivers/video/fbdev/cyber2000fb.c |    1 -
    drivers/video/fbdev/i740fb.c  |    1 -
    drivers/video/fbdev/intelfb/intelfb_i2c.c |   15 +--
    drivers/video/fbdev/matrox/i2c-matroxfb.c |   12 
    drivers/video/fbdev/s3fb.c    |    1 -
    drivers/video/fbdev/tdfxfb.c  |    1 -
    drivers/video/fbdev/tridentfb.c   |    1 -
    drivers/video/fbdev/via/via_i2c.c |    1 -
    include/linux/i2c.h   |    1 -
    31 files changed, 9 insertions(+), 47 deletions(-)










--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH v4 00/20] remove I2C_CLASS_DDC support

2023-11-23 Thread Thomas Zimmermann

Hi

Am 23.11.23 um 08:16 schrieb Heiner Kallweit:

On 23.11.2023 07:56, Thomas Zimmermann wrote:

Hi

Am 20.11.23 um 22:46 schrieb Heiner Kallweit:

After removal of the legacy EEPROM driver and I2C_CLASS_DDC support in
olpc_dcon there's no i2c client driver left supporting I2C_CLASS_DDC.
Class-based device auto-detection is a legacy mechanism and shouldn't
be used in new code. So we can remove this class completely now.

Preferably this series should be applied via the i2c tree.

v2:
- change tag in commit subject of patch 03
- add ack tags
v3:
- fix a compile error in patch 5
v4:
- more ack and review tags

Signed-off-by: Heiner Kallweit 


Acked-by: Thomas Zimmermann 

for the patches that don't already have my r-b.


This refers to which patches of the series?
Patches 8, 16, 18 are the remaining ones w/o A-b or R-b.


I've looked through the patchset. Feel free to add my a-b to patches 1 
to 19; except for 2 and 17, which already have my r-b.


BTW I only received 19 patches. is there a patch 20/20?

Best regards
Thomas




Best regards
Thomas


Thanks, Heiner



---

   drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c   |    1 -
   drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |    1 -
   drivers/gpu/drm/ast/ast_i2c.c |    1 -
   drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |    1 -
   drivers/gpu/drm/display/drm_dp_helper.c   |    1 -
   drivers/gpu/drm/display/drm_dp_mst_topology.c |    1 -
   drivers/gpu/drm/gma500/cdv_intel_dp.c |    1 -
   drivers/gpu/drm/gma500/intel_gmbus.c  |    1 -
   drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c    |    1 -
   drivers/gpu/drm/gma500/psb_intel_sdvo.c   |    1 -
   drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c   |    1 -
   drivers/gpu/drm/i915/display/intel_gmbus.c    |    1 -
   drivers/gpu/drm/i915/display/intel_sdvo.c |    1 -
   drivers/gpu/drm/loongson/lsdc_i2c.c   |    1 -
   drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c   |    1 -
   drivers/gpu/drm/mgag200/mgag200_i2c.c |    1 -
   drivers/gpu/drm/msm/hdmi/hdmi_i2c.c   |    1 -
   drivers/gpu/drm/radeon/radeon_i2c.c   |    1 -
   drivers/gpu/drm/rockchip/inno_hdmi.c  |    1 -
   drivers/gpu/drm/rockchip/rk3066_hdmi.c    |    1 -
   drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c    |    1 -
   drivers/video/fbdev/core/fb_ddc.c |    1 -
   drivers/video/fbdev/cyber2000fb.c |    1 -
   drivers/video/fbdev/i740fb.c  |    1 -
   drivers/video/fbdev/intelfb/intelfb_i2c.c |   15 +--
   drivers/video/fbdev/matrox/i2c-matroxfb.c |   12 
   drivers/video/fbdev/s3fb.c    |    1 -
   drivers/video/fbdev/tdfxfb.c  |    1 -
   drivers/video/fbdev/tridentfb.c   |    1 -
   drivers/video/fbdev/via/via_i2c.c |    1 -
   include/linux/i2c.h   |    1 -
   31 files changed, 9 insertions(+), 47 deletions(-)






--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH v4 00/20] remove I2C_CLASS_DDC support

2023-11-22 Thread Thomas Zimmermann

Hi

Am 20.11.23 um 22:46 schrieb Heiner Kallweit:

After removal of the legacy EEPROM driver and I2C_CLASS_DDC support in
olpc_dcon there's no i2c client driver left supporting I2C_CLASS_DDC.
Class-based device auto-detection is a legacy mechanism and shouldn't
be used in new code. So we can remove this class completely now.

Preferably this series should be applied via the i2c tree.

v2:
- change tag in commit subject of patch 03
- add ack tags
v3:
- fix a compile error in patch 5
v4:
- more ack and review tags

Signed-off-by: Heiner Kallweit 


Acked-by: Thomas Zimmermann 

for the patches that don't already have my r-b.

Best regards
Thomas



---

  drivers/gpu/drm/amd/amdgpu/amdgpu_i2c.c   |1 -
  drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c |1 -
  drivers/gpu/drm/ast/ast_i2c.c |1 -
  drivers/gpu/drm/bridge/synopsys/dw-hdmi.c |1 -
  drivers/gpu/drm/display/drm_dp_helper.c   |1 -
  drivers/gpu/drm/display/drm_dp_mst_topology.c |1 -
  drivers/gpu/drm/gma500/cdv_intel_dp.c |1 -
  drivers/gpu/drm/gma500/intel_gmbus.c  |1 -
  drivers/gpu/drm/gma500/oaktrail_hdmi_i2c.c|1 -
  drivers/gpu/drm/gma500/psb_intel_sdvo.c   |1 -
  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c   |1 -
  drivers/gpu/drm/i915/display/intel_gmbus.c|1 -
  drivers/gpu/drm/i915/display/intel_sdvo.c |1 -
  drivers/gpu/drm/loongson/lsdc_i2c.c   |1 -
  drivers/gpu/drm/mediatek/mtk_hdmi_ddc.c   |1 -
  drivers/gpu/drm/mgag200/mgag200_i2c.c |1 -
  drivers/gpu/drm/msm/hdmi/hdmi_i2c.c   |1 -
  drivers/gpu/drm/radeon/radeon_i2c.c   |1 -
  drivers/gpu/drm/rockchip/inno_hdmi.c  |1 -
  drivers/gpu/drm/rockchip/rk3066_hdmi.c|1 -
  drivers/gpu/drm/sun4i/sun4i_hdmi_i2c.c|1 -
  drivers/video/fbdev/core/fb_ddc.c |1 -
  drivers/video/fbdev/cyber2000fb.c |1 -
  drivers/video/fbdev/i740fb.c  |1 -
  drivers/video/fbdev/intelfb/intelfb_i2c.c |   15 +--
  drivers/video/fbdev/matrox/i2c-matroxfb.c |   12 
  drivers/video/fbdev/s3fb.c|1 -
  drivers/video/fbdev/tdfxfb.c  |1 -
  drivers/video/fbdev/tridentfb.c   |1 -
  drivers/video/fbdev/via/via_i2c.c |1 -
  include/linux/i2c.h   |1 -
  31 files changed, 9 insertions(+), 47 deletions(-)


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature.asc
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH RFC v1 00/52] drm/crtc: Rename struct drm_crtc::dev to drm_dev

2023-07-14 Thread Thomas Zimmermann

Hi

Am 13.07.23 um 17:14 schrieb Tvrtko Ursulin:


On 13/07/2023 16:09, Thomas Zimmermann wrote:

Hi

Am 13.07.23 um 16:41 schrieb Sean Paul:

On Thu, Jul 13, 2023 at 9:04 AM Uwe Kleine-König
 wrote:


hello Sean,

On Wed, Jul 12, 2023 at 02:31:02PM -0400, Sean Paul wrote:

I'd really prefer this patch (series or single) is not accepted. This
will cause problems for everyone cherry-picking patches to a
downstream kernel (LTS or distro tree). I usually wouldn't expect
sympathy here, but the questionable benefit does not outweigh the cost
IM[biased]O.


I agree that for backports this isn't so nice. However with the split
approach (that was argumented against here) it's not soo bad. Patch #1
(and similar changes for the other affected structures) could be
trivially backported and with that it doesn't matter if you write 
dev or

drm (or whatever name is chosen in the end); both work in the same way.


Patch #1 avoids the need to backport the entire set, however every
change occuring after the rename patches will cause conflicts on
future cherry-picks. Downstream kernels will have to backport the
whole set. Backporting the entire set will create an epoch in
downstream kernels where cherry-picking patches preceding this set
will need to undergo conflict resolution as well. As mentioned in my
previous email, I don't expect sympathy here, it's part of maintaining
a downstream kernel, but there is a real cost to kernel consumers.



But even with the one-patch-per-rename approach I'd consider the
renaming a net win, because ease of understanding code has a big value.
It's value is not so easy measurable as "conflicts when backporting",
but it also matters in say two years from now, while backporting
shouldn't be an issue then any more.


You've rightly identified the conjecture in your statement. I've been
on both sides of the argument, having written/maintained drm code
upstream and cherry-picked changes to a downstream kernel. Perhaps
it's because drm's definition of dev is ingrained in my muscle memory,
or maybe it's because I don't do a lot of upstream development these
days, but I just have a hard time seeing the benefit here.


I can only second what Sean writes. I've done quite a bit of 
backporting of DRM code. It's hard already. And this kind of change is 
going to to affect almost every backported DRM patch in the coming 
years. Not just for distribution kernels, but also for upstream's 
stable series. It's really only possible to do this change over many 
releases while keeping compatible with the old name. So the more I 
think about it, the less I like this change.


I've done my share of backporting, and still am doing it, so I can say I 
dislike it as much as anyone, however.. Is this an argument which the 
kernel as a wider entity typically accepts? If not could it be a 
slippery slope to start a precedent?


IMHO upstream patches should only be judged by their effect on the 
upstream. Backporting, API stability, out-of-tree drivers, etc should 
not be a concern. I think that we (the DRM devs) are mostly living up to 
that ideal. OTOH if a change has been accepted, it's fair to ask how to 
make it in the least intrusive way.


But with this change, it doesn't add up for me. The benefit to Linux is 
rather cosmetic. And the possible downsides are significant even if we 
ignore downstream distribution kernels. Merging between DRM trees will 
be affected, backporting into stable kernels as well, the rename will 
mess up git blame with rename commits.


Best regards
Thomas



It is a honest question - I am not familiar if there were or were not 
any similar discussions in the past.


My gut feeling is that *if* there is a consensus that something 
_improves_ the code base significantly, backporting pains should 
probably not be weighted very heavily as a contra argument.


Regards,

Tvrtko


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH RFC v1 00/52] drm/crtc: Rename struct drm_crtc::dev to drm_dev

2023-07-13 Thread Thomas Zimmermann

Hi

Am 13.07.23 um 16:41 schrieb Sean Paul:

On Thu, Jul 13, 2023 at 9:04 AM Uwe Kleine-König
 wrote:


hello Sean,

On Wed, Jul 12, 2023 at 02:31:02PM -0400, Sean Paul wrote:

I'd really prefer this patch (series or single) is not accepted. This
will cause problems for everyone cherry-picking patches to a
downstream kernel (LTS or distro tree). I usually wouldn't expect
sympathy here, but the questionable benefit does not outweigh the cost
IM[biased]O.


I agree that for backports this isn't so nice. However with the split
approach (that was argumented against here) it's not soo bad. Patch #1
(and similar changes for the other affected structures) could be
trivially backported and with that it doesn't matter if you write dev or
drm (or whatever name is chosen in the end); both work in the same way.


Patch #1 avoids the need to backport the entire set, however every
change occuring after the rename patches will cause conflicts on
future cherry-picks. Downstream kernels will have to backport the
whole set. Backporting the entire set will create an epoch in
downstream kernels where cherry-picking patches preceding this set
will need to undergo conflict resolution as well. As mentioned in my
previous email, I don't expect sympathy here, it's part of maintaining
a downstream kernel, but there is a real cost to kernel consumers.



But even with the one-patch-per-rename approach I'd consider the
renaming a net win, because ease of understanding code has a big value.
It's value is not so easy measurable as "conflicts when backporting",
but it also matters in say two years from now, while backporting
shouldn't be an issue then any more.


You've rightly identified the conjecture in your statement. I've been
on both sides of the argument, having written/maintained drm code
upstream and cherry-picked changes to a downstream kernel. Perhaps
it's because drm's definition of dev is ingrained in my muscle memory,
or maybe it's because I don't do a lot of upstream development these
days, but I just have a hard time seeing the benefit here.


I can only second what Sean writes. I've done quite a bit of backporting 
of DRM code. It's hard already. And this kind of change is going to to 
affect almost every backported DRM patch in the coming years. Not just 
for distribution kernels, but also for upstream's stable series. It's 
really only possible to do this change over many releases while keeping 
compatible with the old name. So the more I think about it, the less I 
like this change.


Best regards
Thomas



I appreciate your engagement on the topic, thank you!

Sean



Thanks for your input, best regards
Uwe

--
Pengutronix e.K.   | Uwe Kleine-König    |
Industrial Linux Solutions | https://www.pengutronix.de/ |


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH RFC v1 00/52] drm/crtc: Rename struct drm_crtc::dev to drm_dev

2023-07-13 Thread Thomas Zimmermann
   |   2 +-
  drivers/gpu/drm/radeon/atombios_crtc.c|  54 +++---
  drivers/gpu/drm/radeon/radeon_cursor.c|  14 +-
  drivers/gpu/drm/radeon/radeon_display.c   |  28 ++--
  drivers/gpu/drm/radeon/radeon_kms.c   |   6 +-
  drivers/gpu/drm/radeon/radeon_legacy_crtc.c   |  16 +-
  .../gpu/drm/renesas/rcar-du/rcar_du_crtc.c|  14 +-
  .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c |  20 +--
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c   |   8 +-
  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  |  15 +-
  drivers/gpu/drm/solomon/ssd130x.c |   2 +-
  drivers/gpu/drm/sprd/sprd_dpu.c   |   6 +-
  drivers/gpu/drm/sti/sti_crtc.c|  14 +-
  drivers/gpu/drm/stm/ltdc.c|  12 +-
  drivers/gpu/drm/sun4i/sun4i_crtc.c|  12 +-
  drivers/gpu/drm/tegra/dc.c|  12 +-
  drivers/gpu/drm/tidss/tidss_crtc.c|  19 ++-
  drivers/gpu/drm/tidss/tidss_irq.c |   4 +-
  drivers/gpu/drm/tilcdc/tilcdc_crtc.c  |  43 ++---
  drivers/gpu/drm/tiny/bochs.c  |   6 +-
  drivers/gpu/drm/tiny/cirrus.c |   2 +-
  drivers/gpu/drm/tiny/gm12u320.c   |   4 +-
  drivers/gpu/drm/tiny/hx8357d.c|   4 +-
  drivers/gpu/drm/tiny/ili9163.c|   4 +-
  drivers/gpu/drm/tiny/ili9225.c|   8 +-
  drivers/gpu/drm/tiny/ili9341.c|   4 +-
  drivers/gpu/drm/tiny/ili9486.c|   4 +-
  drivers/gpu/drm/tiny/mi0283qt.c   |   4 +-
  drivers/gpu/drm/tiny/ofdrm.c  |   8 +-
  drivers/gpu/drm/tiny/panel-mipi-dbi.c |   6 +-
  drivers/gpu/drm/tiny/repaper.c|   8 +-
  drivers/gpu/drm/tiny/simpledrm.c  |   2 +-
  drivers/gpu/drm/tiny/st7586.c |   6 +-
  drivers/gpu/drm/tiny/st7735r.c|   4 +-
  drivers/gpu/drm/tve200/tve200_display.c   |  14 +-
  drivers/gpu/drm/udl/udl_modeset.c |   4 +-
  drivers/gpu/drm/vboxvideo/vbox_mode.c |   6 +-
  drivers/gpu/drm/vc4/vc4_crtc.c|  38 ++---
  drivers/gpu/drm/vc4/vc4_hdmi.c|   2 +-
  drivers/gpu/drm/vc4/vc4_hvs.c |  12 +-
  drivers/gpu/drm/vc4/vc4_txp.c |   2 +-
  drivers/gpu/drm/virtio/virtgpu_display.c  |   4 +-
  drivers/gpu/drm/vkms/vkms_crtc.c  |  12 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |   4 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c  |  10 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c  |   8 +-
  drivers/gpu/drm/xen/xen_drm_front_kms.c   |  10 +-
  drivers/gpu/drm/xlnx/zynqmp_kms.c |   8 +-
  include/drm/drm_atomic_helper.h   |   2 +-
  include/drm/drm_crtc.h|   4 +-
  194 files changed, 1296 insertions(+), 1264 deletions(-)

base-commit: 06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH RFC v1 00/52] drm/crtc: Rename struct drm_crtc::dev to drm_dev

2023-07-13 Thread Thomas Zimmermann

Hi

Am 12.07.23 um 20:31 schrieb Sean Paul:

On Wed, Jul 12, 2023 at 10:52 AM Jani Nikula  wrote:


On Wed, 12 Jul 2023, Uwe Kleine-König  wrote:

Hello,

while I debugged an issue in the imx-lcdc driver I was constantly
irritated about struct drm_device pointer variables being named "dev"
because with that name I usually expect a struct device pointer.

I think there is a big benefit when these are all renamed to "drm_dev".
I have no strong preference here though, so "drmdev" or "drm" are fine
for me, too. Let the bikesheding begin!

Some statistics:

$ git grep -ohE 'struct drm_device *\* *[^ (),;]*' v6.5-rc1 | sort | uniq -c | 
sort -n
   1 struct drm_device *adev_to_drm
   1 struct drm_device *drm_
   1 struct drm_device  *drm_dev
   1 struct drm_device*drm_dev
   1 struct drm_device *pdev
   1 struct drm_device *rdev
   1 struct drm_device *vdev
   2 struct drm_device *dcss_drv_dev_to_drm
   2 struct drm_device **ddev
   2 struct drm_device *drm_dev_alloc
   2 struct drm_device *mock
   2 struct drm_device *p_ddev
   5 struct drm_device *device
   9 struct drm_device * dev
  25 struct drm_device *d
  95 struct drm_device *
 216 struct drm_device *ddev
 234 struct drm_device *drm_dev
 611 struct drm_device *drm
4190 struct drm_device *dev

This series starts with renaming struct drm_crtc::dev to drm_dev. If
it's not only me and others like the result of this effort it should be
followed up by adapting the other structs and the individual usages in
the different drivers.


I think this is an unnecessary change. In drm, a dev is usually a drm
device, i.e. struct drm_device *. As shown by the numbers above.



I'd really prefer this patch (series or single) is not accepted. This
will cause problems for everyone cherry-picking patches to a
downstream kernel (LTS or distro tree). I usually wouldn't expect
sympathy here, but the questionable benefit does not outweigh the cost
IM[biased]O.


I agree.



Sean


If folks insist on following through with this anyway, I'm firmly in the
camp the name should be "drm" and nothing else.


BR,
Jani.


--
Jani Nikula, Intel Open Source Graphics Center


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH RFC v1 00/52] drm/crtc: Rename struct drm_crtc::dev to drm_dev

2023-07-13 Thread Thomas Zimmermann

Hi

Am 12.07.23 um 18:10 schrieb Uwe Kleine-König:

Hello Jani,

On Wed, Jul 12, 2023 at 05:34:28PM +0300, Jani Nikula wrote:

On Wed, 12 Jul 2023, Uwe Kleine-König  wrote:

Hello,

while I debugged an issue in the imx-lcdc driver I was constantly
irritated about struct drm_device pointer variables being named "dev"
because with that name I usually expect a struct device pointer.

I think there is a big benefit when these are all renamed to "drm_dev".
I have no strong preference here though, so "drmdev" or "drm" are fine
for me, too. Let the bikesheding begin!

Some statistics:

$ git grep -ohE 'struct drm_device *\* *[^ (),;]*' v6.5-rc1 | sort | uniq -c | 
sort -n
   1 struct drm_device *adev_to_drm
   1 struct drm_device *drm_
   1 struct drm_device  *drm_dev
   1 struct drm_device*drm_dev
   1 struct drm_device *pdev
   1 struct drm_device *rdev
   1 struct drm_device *vdev
   2 struct drm_device *dcss_drv_dev_to_drm
   2 struct drm_device **ddev
   2 struct drm_device *drm_dev_alloc
   2 struct drm_device *mock
   2 struct drm_device *p_ddev
   5 struct drm_device *device
   9 struct drm_device * dev
  25 struct drm_device *d
  95 struct drm_device *
 216 struct drm_device *ddev
 234 struct drm_device *drm_dev
 611 struct drm_device *drm
4190 struct drm_device *dev

This series starts with renaming struct drm_crtc::dev to drm_dev. If
it's not only me and others like the result of this effort it should be
followed up by adapting the other structs and the individual usages in
the different drivers.


I think this is an unnecessary change. In drm, a dev is usually a drm
device, i.e. struct drm_device *.


Well, unless it's not. Prominently there is

struct drm_device {
...
struct device *dev;
...
};


Jani's point is that it's only inconvenient at the first time. Everyone 
gets use to it.


Best regards
Thomas



which yields quite a few code locations using dev->dev which is
IMHO unnecessary irritating:

$ git grep '\dev' v6.5-rc1 drivers/gpu/drm | wc -l
1633

Also the functions that deal with both a struct device and a struct
drm_device often use "dev" for the struct device and then "ddev" for
the drm_device (see for example amdgpu_device_get_pcie_replay_count()).


If folks insist on following through with this anyway, I'm firmly in the
camp the name should be "drm" and nothing else.


Up to now positive feedback is in the majority.

Best regards
Uwe



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH RFC v1 00/52] drm/crtc: Rename struct drm_crtc::dev to drm_dev

2023-07-12 Thread Thomas Zimmermann
rivers/gpu/drm/radeon/radeon_display.c   |  28 ++--
  drivers/gpu/drm/radeon/radeon_kms.c   |   6 +-
  drivers/gpu/drm/radeon/radeon_legacy_crtc.c   |  16 +-
  .../gpu/drm/renesas/rcar-du/rcar_du_crtc.c|  14 +-
  .../gpu/drm/renesas/shmobile/shmob_drm_crtc.c |  20 +--
  drivers/gpu/drm/rockchip/rockchip_drm_vop.c   |   8 +-
  drivers/gpu/drm/rockchip/rockchip_drm_vop2.c  |  15 +-
  drivers/gpu/drm/solomon/ssd130x.c |   2 +-
  drivers/gpu/drm/sprd/sprd_dpu.c   |   6 +-
  drivers/gpu/drm/sti/sti_crtc.c|  14 +-
  drivers/gpu/drm/stm/ltdc.c|  12 +-
  drivers/gpu/drm/sun4i/sun4i_crtc.c|  12 +-
  drivers/gpu/drm/tegra/dc.c|  12 +-
  drivers/gpu/drm/tidss/tidss_crtc.c|  19 ++-
  drivers/gpu/drm/tidss/tidss_irq.c |   4 +-
  drivers/gpu/drm/tilcdc/tilcdc_crtc.c  |  43 ++---
  drivers/gpu/drm/tiny/bochs.c  |   6 +-
  drivers/gpu/drm/tiny/cirrus.c |   2 +-
  drivers/gpu/drm/tiny/gm12u320.c   |   4 +-
  drivers/gpu/drm/tiny/hx8357d.c|   4 +-
  drivers/gpu/drm/tiny/ili9163.c|   4 +-
  drivers/gpu/drm/tiny/ili9225.c|   8 +-
  drivers/gpu/drm/tiny/ili9341.c|   4 +-
  drivers/gpu/drm/tiny/ili9486.c|   4 +-
  drivers/gpu/drm/tiny/mi0283qt.c   |   4 +-
  drivers/gpu/drm/tiny/ofdrm.c  |   8 +-
  drivers/gpu/drm/tiny/panel-mipi-dbi.c |   6 +-
  drivers/gpu/drm/tiny/repaper.c|   8 +-
  drivers/gpu/drm/tiny/simpledrm.c  |   2 +-
  drivers/gpu/drm/tiny/st7586.c |   6 +-
  drivers/gpu/drm/tiny/st7735r.c|   4 +-
  drivers/gpu/drm/tve200/tve200_display.c   |  14 +-
  drivers/gpu/drm/udl/udl_modeset.c |   4 +-
  drivers/gpu/drm/vboxvideo/vbox_mode.c |   6 +-
  drivers/gpu/drm/vc4/vc4_crtc.c|  38 ++---
  drivers/gpu/drm/vc4/vc4_hdmi.c|   2 +-
  drivers/gpu/drm/vc4/vc4_hvs.c |  12 +-
  drivers/gpu/drm/vc4/vc4_txp.c |   2 +-
  drivers/gpu/drm/virtio/virtgpu_display.c  |   4 +-
  drivers/gpu/drm/vkms/vkms_crtc.c  |  12 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_kms.c   |   4 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_scrn.c  |  10 +-
  drivers/gpu/drm/vmwgfx/vmwgfx_stdu.c  |   8 +-
  drivers/gpu/drm/xen/xen_drm_front_kms.c   |  10 +-
  drivers/gpu/drm/xlnx/zynqmp_kms.c |   8 +-
  include/drm/drm_atomic_helper.h   |   2 +-
  include/drm/drm_crtc.h|   4 +-
  194 files changed, 1296 insertions(+), 1264 deletions(-)

base-commit: 06c2afb862f9da8dc5efa4b6076a0e48c3fbaaa5


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH] drm/client: Send hotplug event after registering a client

2023-07-10 Thread Thomas Zimmermann

Hi

Am 10.07.23 um 23:11 schrieb Dmitry Baryshkov:
[...]

---
  drivers/gpu/drm/armada/armada_fbdev.c |  4 
  drivers/gpu/drm/drm_client.c  | 21 +
  drivers/gpu/drm/drm_fbdev_dma.c   |  4 
  drivers/gpu/drm/drm_fbdev_generic.c   |  4 
  drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  4 
  drivers/gpu/drm/gma500/fbdev.c    |  4 
  drivers/gpu/drm/msm/msm_fbdev.c   |  4 


Reviewed-by: Dmitry Baryshkov  # msm


Thanks.




  drivers/gpu/drm/omapdrm/omap_fbdev.c  |  4 
  drivers/gpu/drm/radeon/radeon_fbdev.c |  4 
  drivers/gpu/drm/tegra/fbdev.c |  4 
  10 files changed, 21 insertions(+), 36 deletions(-)


BTW: As you have been clearing this area. I see that significant amount 
of DRM drivers use exactly the same code for msm_fbdev_client_funcs and 
for the significant part of foo_fbdev_setup(). Do you have any plans for 
moving that into a library / generic code? If not, I can take a look at 
crafting the patch.




You're not the first to ask. :) I've so far not attempted to address 
this duplication. I've been bitten by premature helperization before, so 
I wanted to wait a bit longer. A lot of the fbdev and client code is 
changing quite a bit. After things stabilized, I want to to try to do 
some more code sharing.


Best regards
Thomas

--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH] drm/client: Send hotplug event after registering a client

2023-07-10 Thread Thomas Zimmermann

Hi

Am 10.07.23 um 11:52 schrieb Javier Martinez Canillas:

Thomas Zimmermann  writes:

Hello Thomas,


Generate a hotplug event after registering a client to allow the
client to configure its display. Remove the hotplug calls from the
existing clients for fbdev emulation. This change fixes a concurrency
bug between registering a client and receiving events from the DRM
core. The bug is present in the fbdev emulation of all drivers.

The fbdev emulation currently generates a hotplug event before
registering the client to the device. For each new output, the DRM
core sends an additional hotplug event to each registered client.

If the DRM core detects first output between sending the artificial
hotplug and registering the device, the output's hotplug event gets
lost. If this is the first output, the fbdev console display remains
dark. This has been observed with amdgpu and fbdev-generic.

Fix this by adding hotplug generation directly to the client's
register helper drm_client_register(). Registering the client and
receiving events are serialized by struct drm_device.clientlist_mutex.
So an output is either configured by the initial hotplug event, or
the client has already been registered.

The bug was originally added in commit 6e3f17ee73f7 ("drm/fb-helper:
generic: Call drm_client_add() after setup is done"), in which adding
a client and receiving a hotplug event switched order. It was hidden,
as most hardware and drivers have at least on static output configured.
Other drivers didn't use the internal DRM client or still had struct
drm_mode_config_funcs.output_poll_changed set. That callback handled
hotplug events as well. After not setting the callback in amdgpu in
commit 0e3172bac3f4 ("drm/amdgpu: Don't set struct
drm_driver.output_poll_changed"), amdgpu did not show a framebuffer
console if output events got lost. The bug got copy-pasted from
fbdev-generic into the other fbdev emulation.

Reported-by: Moritz Duge 
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/2649


Aren't you missing a Fixes: for 0e3172bac3f4 too? Since that's the commit
that unmasked the bug for amdgpu, IMO that is the most important to list.


Well, OK.




Fixes: 6e3f17ee73f7 ("drm/fb-helper: generic: Call drm_client_add() after setup is 
done")
Fixes: 8ab59da26bc0 ("drm/fb-helper: Move generic fbdev emulation into separate 
source file")
Fixes: b79fe9abd58b ("drm/fbdev-dma: Implement fbdev emulation for GEM DMA 
helpers")
Fixes: 63c381552f69 ("drm/armada: Implement fbdev emulation as in-kernel 
client")
Fixes: 49953b70e7d3 ("drm/exynos: Implement fbdev emulation as in-kernel 
client")
Fixes: 8f1aaccb04b7 ("drm/gma500: Implement client-based fbdev emulation")
Fixes: 940b869c2f2f ("drm/msm: Implement fbdev emulation as in-kernel client")
Fixes: 9e69bcd88e45 ("drm/omapdrm: Implement fbdev emulation as in-kernel 
client")
Fixes: e317a69fe891 ("drm/radeon: Implement client-based fbdev emulation")
Fixes: 71ec16f45ef8 ("drm/tegra: Implement fbdev emulation as in-kernel client")
Signed-off-by: Thomas Zimmermann 
Tested-by: Moritz Duge 
Tested-by: Torsten Krah 
Tested-by: Paul Schyska 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Noralf Trønnes 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Javier Martinez Canillas 
Cc: Russell King 
Cc: Inki Dae 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Krzysztof Kozlowski 
Cc: Patrik Jakobsson 
Cc: Rob Clark 
Cc: Abhinav Kumar 
Cc: Dmitry Baryshkov 
Cc: Tomi Valkeinen 
Cc: Alex Deucher 
Cc: "Christian König" 
Cc: "Pan, Xinhui" 
Cc: Thierry Reding 
Cc: Mikko Perttunen 
Cc: dri-de...@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-arm-...@vger.kernel.org
Cc: freedreno@lists.freedesktop.org
Cc: amd-...@lists.freedesktop.org
Cc: linux-te...@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Cc:  # v5.2+


While it's true that the but was introduced by commit 6e3f17ee73f7 and that
landed in v5.2, I wonder if this patch could even be applied to such olders
Linux versions. Probably in practice it would be at most backported to
v6.2, which is the release that exposed the bug for the amdgpu driver.


No idea. The fix looks simple enough, but a lot has changed in the 
surrounding code.


Best regards
Thomas



Your explanation makes sense to me and the patch looks good.

Reviewed-by: Javier Martinez Canillas 



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature
Description: OpenPGP digital signature


[Freedreno] [PATCH] drm/client: Send hotplug event after registering a client

2023-07-10 Thread Thomas Zimmermann
Generate a hotplug event after registering a client to allow the
client to configure its display. Remove the hotplug calls from the
existing clients for fbdev emulation. This change fixes a concurrency
bug between registering a client and receiving events from the DRM
core. The bug is present in the fbdev emulation of all drivers.

The fbdev emulation currently generates a hotplug event before
registering the client to the device. For each new output, the DRM
core sends an additional hotplug event to each registered client.

If the DRM core detects first output between sending the artificial
hotplug and registering the device, the output's hotplug event gets
lost. If this is the first output, the fbdev console display remains
dark. This has been observed with amdgpu and fbdev-generic.

Fix this by adding hotplug generation directly to the client's
register helper drm_client_register(). Registering the client and
receiving events are serialized by struct drm_device.clientlist_mutex.
So an output is either configured by the initial hotplug event, or
the client has already been registered.

The bug was originally added in commit 6e3f17ee73f7 ("drm/fb-helper:
generic: Call drm_client_add() after setup is done"), in which adding
a client and receiving a hotplug event switched order. It was hidden,
as most hardware and drivers have at least on static output configured.
Other drivers didn't use the internal DRM client or still had struct
drm_mode_config_funcs.output_poll_changed set. That callback handled
hotplug events as well. After not setting the callback in amdgpu in
commit 0e3172bac3f4 ("drm/amdgpu: Don't set struct
drm_driver.output_poll_changed"), amdgpu did not show a framebuffer
console if output events got lost. The bug got copy-pasted from
fbdev-generic into the other fbdev emulation.

Reported-by: Moritz Duge 
Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/2649
Fixes: 6e3f17ee73f7 ("drm/fb-helper: generic: Call drm_client_add() after setup 
is done")
Fixes: 8ab59da26bc0 ("drm/fb-helper: Move generic fbdev emulation into separate 
source file")
Fixes: b79fe9abd58b ("drm/fbdev-dma: Implement fbdev emulation for GEM DMA 
helpers")
Fixes: 63c381552f69 ("drm/armada: Implement fbdev emulation as in-kernel 
client")
Fixes: 49953b70e7d3 ("drm/exynos: Implement fbdev emulation as in-kernel 
client")
Fixes: 8f1aaccb04b7 ("drm/gma500: Implement client-based fbdev emulation")
Fixes: 940b869c2f2f ("drm/msm: Implement fbdev emulation as in-kernel client")
Fixes: 9e69bcd88e45 ("drm/omapdrm: Implement fbdev emulation as in-kernel 
client")
Fixes: e317a69fe891 ("drm/radeon: Implement client-based fbdev emulation")
Fixes: 71ec16f45ef8 ("drm/tegra: Implement fbdev emulation as in-kernel client")
Signed-off-by: Thomas Zimmermann 
Tested-by: Moritz Duge 
Tested-by: Torsten Krah 
Tested-by: Paul Schyska 
Cc: Daniel Vetter 
Cc: David Airlie 
Cc: Noralf Trønnes 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Javier Martinez Canillas 
Cc: Russell King 
Cc: Inki Dae 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Krzysztof Kozlowski 
Cc: Patrik Jakobsson 
Cc: Rob Clark 
Cc: Abhinav Kumar 
Cc: Dmitry Baryshkov 
Cc: Tomi Valkeinen 
Cc: Alex Deucher 
Cc: "Christian König" 
Cc: "Pan, Xinhui" 
Cc: Thierry Reding 
Cc: Mikko Perttunen 
Cc: dri-de...@lists.freedesktop.org
Cc: linux-ker...@vger.kernel.org
Cc: linux-arm-ker...@lists.infradead.org
Cc: linux-samsung-...@vger.kernel.org
Cc: linux-arm-...@vger.kernel.org
Cc: freedreno@lists.freedesktop.org
Cc: amd-...@lists.freedesktop.org
Cc: linux-te...@vger.kernel.org
Cc: dri-de...@lists.freedesktop.org
Cc:  # v5.2+
---
 drivers/gpu/drm/armada/armada_fbdev.c |  4 
 drivers/gpu/drm/drm_client.c  | 21 +
 drivers/gpu/drm/drm_fbdev_dma.c   |  4 
 drivers/gpu/drm/drm_fbdev_generic.c   |  4 
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c |  4 
 drivers/gpu/drm/gma500/fbdev.c|  4 
 drivers/gpu/drm/msm/msm_fbdev.c   |  4 
 drivers/gpu/drm/omapdrm/omap_fbdev.c  |  4 
 drivers/gpu/drm/radeon/radeon_fbdev.c |  4 
 drivers/gpu/drm/tegra/fbdev.c |  4 
 10 files changed, 21 insertions(+), 36 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_fbdev.c 
b/drivers/gpu/drm/armada/armada_fbdev.c
index 3943e89cc06c..e40a95e51785 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -209,10 +209,6 @@ void armada_fbdev_setup(struct drm_device *dev)
goto err_drm_client_init;
}
 
-   ret = armada_fbdev_client_hotplug(&fbh->client);
-   if (ret)
-   drm_dbg_kms(dev, "client hotplug ret=%d\n", ret);
-
drm_client_register(&fbh->client);
 
return;
diff --git a/drivers/gpu/drm/drm_client.c b/driver

Re: [Freedreno] [PATCH v5 02/13] fbdev: Add initializer macros for struct fb_ops

2023-06-14 Thread Thomas Zimmermann

Hi

Am 14.06.23 um 13:29 schrieb Christian König:



Am 30.05.23 um 17:02 schrieb Thomas Zimmermann:

For framebuffers in I/O and system memory, add macros that set
struct fb_ops to the respective callback functions.

For deferred I/O, add macros that generate callback functions with
damage handling. Add initializer macros that set struct fb_ops to
the generated callbacks.

These macros can remove a lot boilerplate code from fbdev drivers.
The drivers are supposed to use the macro that is required for its
framebuffer. Each macro is split into smaller helpers, so that
drivers with non-standard callbacks can pick and customize callbacks
as needed. There are individual helper macros for read/write, mmap
and drawing.

v5:
* fix whitespace errors (Jingfeng)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Sam Ravnborg 
---
  include/linux/fb.h | 112 +
  1 file changed, 112 insertions(+)

diff --git a/include/linux/fb.h b/include/linux/fb.h
index 2cf8efcb9e32..ce6823e157e6 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -538,9 +538,31 @@ extern ssize_t fb_io_read(struct fb_info *info, 
char __user *buf,
  extern ssize_t fb_io_write(struct fb_info *info, const char __user 
*buf,

 size_t count, loff_t *ppos);
+/*
+ * Initializes struct fb_ops for framebuffers in I/O memory.
+ */
+
+#define __FB_DEFAULT_IO_OPS_RDWR \
+    .fb_read    = fb_io_read, \
+    .fb_write    = fb_io_write
+
+#define __FB_DEFAULT_IO_OPS_DRAW \
+    .fb_fillrect    = cfb_fillrect, \
+    .fb_copyarea    = cfb_copyarea, \
+    .fb_imageblit    = cfb_imageblit
+
+#define __FB_DEFAULT_IO_OPS_MMAP \
+    .fb_mmap    = NULL // default implementation


// style comment in a macro? That's usually a very bad idea.


I think I see it now. Thanks! That should delete any commas at the end 
of the line. I'll send out an update. It works so far, as I only used 
that macro in the correct way.


Best regards
Thomas



Christian.


+
+#define FB_DEFAULT_IO_OPS \
+    __FB_DEFAULT_IO_OPS_RDWR, \
+    __FB_DEFAULT_IO_OPS_DRAW, \
+    __FB_DEFAULT_IO_OPS_MMAP
+
  /*
   * Drawing operations where framebuffer is in system RAM
   */
+
  extern void sys_fillrect(struct fb_info *info, const struct 
fb_fillrect *rect);
  extern void sys_copyarea(struct fb_info *info, const struct 
fb_copyarea *area);
  extern void sys_imageblit(struct fb_info *info, const struct 
fb_image *image);
@@ -549,6 +571,27 @@ extern ssize_t fb_sys_read(struct fb_info *info, 
char __user *buf,
  extern ssize_t fb_sys_write(struct fb_info *info, const char __user 
*buf,

  size_t count, loff_t *ppos);
+/*
+ * Initializes struct fb_ops for framebuffers in system memory.
+ */
+
+#define __FB_DEFAULT_SYS_OPS_RDWR \
+    .fb_read    = fb_sys_read, \
+    .fb_write    = fb_sys_write
+
+#define __FB_DEFAULT_SYS_OPS_DRAW \
+    .fb_fillrect    = sys_fillrect, \
+    .fb_copyarea    = sys_copyarea, \
+    .fb_imageblit    = sys_imageblit
+
+#define __FB_DEFAULT_SYS_OPS_MMAP \
+    .fb_mmap    = NULL // default implementation
+
+#define FB_DEFAULT_SYS_OPS \
+    __FB_DEFAULT_SYS_OPS_RDWR, \
+    __FB_DEFAULT_SYS_OPS_DRAW, \
+    __FB_DEFAULT_SYS_OPS_MMAP
+
  /* drivers/video/fbmem.c */
  extern int register_framebuffer(struct fb_info *fb_info);
  extern void unregister_framebuffer(struct fb_info *fb_info);
@@ -604,6 +647,75 @@ extern void fb_deferred_io_cleanup(struct fb_info 
*info);

  extern int fb_deferred_io_fsync(struct file *file, loff_t start,
  loff_t end, int datasync);
+/*
+ * Generate callbacks for deferred I/O
+ */
+
+#define __FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, 
__mode) \
+    static ssize_t __prefix ## _defio_read(struct fb_info *info, char 
__user *buf, \

+   size_t count, loff_t *ppos) \
+    { \
+    return fb_ ## __mode ## _read(info, buf, count, ppos); \
+    } \
+    static ssize_t __prefix ## _defio_write(struct fb_info *info, 
const char __user *buf, \

+    size_t count, loff_t *ppos) \
+    { \
+    unsigned long offset = *ppos; \
+    ssize_t ret = fb_ ## __mode ## _write(info, buf, count, ppos); \
+    if (ret > 0) \
+    __damage_range(info, offset, ret); \
+    return ret; \
+    }
+
+#define __FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, 
__mode) \

+    static void __prefix ## _defio_fillrect(struct fb_info *info, \
+    const struct fb_fillrect *rect) \
+    { \
+    __mode ## _fillrect(info, rect); \
+    __damage_area(info, rect->dx, rect->dy, rect->width, 
rect->height); \

+    } \
+    static void __prefix ## _defio_copyarea(struct fb_info *info, \
+    const struct fb_copyarea *area) \
+    { \
+    __mode ## _copyarea(info, area); \
+    __damage_area(info, area->dx, area->dy, area->width, 
area->height); \

+    } \
+    static void __prefix ## 

Re: [Freedreno] [2/2] drm: Remove struct drm_driver.gem_prime_mmap

2023-06-14 Thread Thomas Zimmermann

Hi

Am 14.06.23 um 10:26 schrieb Sui Jingfeng:

Hi,

On 2023/6/14 13:34, Thomas Zimmermann wrote:

Hi

Am 14.06.23 um 04:06 schrieb Sui Jingfeng:


On 2023/6/14 01:27, Sui Jingfeng wrote:

Wow, so many drivers get nuked!

On 2023/6/13 22:51, Thomas Zimmermann wrote:

All drivers initialize this field with drm_gem_prime_mmap(). Call
the function directly and remove the field. Simplifies the code and
resolves a long-standing TODO item.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Alex Deucher 



I have tested this patch briefly with drm/amdgpu(RX560), Running 
glmark2, the rendered scene looks OK.


But single driver is self-sharing.  I think I should test this more 
with multiple video card.



No need to test; it's equivalent to removing a wrapper.


Yes, only msm hardware might be affected.



But new DRM (un-upstreamed) drivers cannot be compiled anymore with 
this patch applied.


This makes them all out-of-date or going to be outdated; this is 
embarrassing!


What do you mean by embarrassing? Simply rebase your driver onto the 
change and that's it. This happens regularly for out-of-tree drivers. 
But if such a driver would land before this patchset, I'd have to 
update the patchset instead.



Thanks for you told me this then.

I worry about what it will happen if two conflict patch got merged 
together.


Yes that occasionaly breaks something, but luckily it rarely results in 
a significant problem.  Drivers that break can be disabled by the 
majority of developers. So that's not an issue for most.  Core code is a 
bit more important. Usually someone provides a patch or workaround quickly.


Best regards
Thomas



If my driver got merged, then one more driver will be nuked together. 
Saving a lot of effort.




Best regards
Thomas






---
  Documentation/gpu/todo.rst  |  9 -
  drivers/accel/ivpu/ivpu_drv.c   |  1 -
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  1 -
  drivers/gpu/drm/drm_fbdev_dma.c |  6 +-
  drivers/gpu/drm/drm_prime.c | 14 ++
  drivers/gpu/drm/etnaviv/etnaviv_drv.c   |  1 -
  drivers/gpu/drm/exynos/exynos_drm_drv.c |  1 -
  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c |  1 -
  drivers/gpu/drm/lima/lima_drv.c |  1 -
  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  1 -
  drivers/gpu/drm/msm/msm_drv.c   |  1 -
  drivers/gpu/drm/msm/msm_drv.h   |  1 -
  drivers/gpu/drm/msm/msm_gem_prime.c |  5 -
  drivers/gpu/drm/nouveau/nouveau_drm.c   |  1 -
  drivers/gpu/drm/panfrost/panfrost_drv.c |  1 -
  drivers/gpu/drm/pl111/pl111_drv.c   |  1 -
  drivers/gpu/drm/radeon/radeon_drv.c |  1 -
  drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c   |  1 -
  drivers/gpu/drm/rockchip/rockchip_drm_drv.c |  1 -
  drivers/gpu/drm/v3d/v3d_drv.c   |  1 -
  drivers/gpu/drm/virtio/virtgpu_drv.c    |  1 -
  drivers/gpu/drm/xen/xen_drm_front.c |  1 -
  include/drm/drm_drv.h   | 14 --
  include/drm/drm_gem_dma_helper.h    |  6 ++
  include/drm/drm_gem_shmem_helper.h  |  1 -
  include/drm/drm_gem_vram_helper.h   |  1 -
  26 files changed, 5 insertions(+), 69 deletions(-)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 68bdafa0284f5..ca1efad8c89c3 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -319,15 +319,6 @@ Contact: Daniel Vetter, Noralf Tronnes
    Level: Advanced
  -struct drm_gem_object_funcs

-
-GEM objects can now have a function table instead of having the 
callbacks on the
-DRM driver struct. This is now the preferred way. Callbacks in 
drivers have been

-converted, except for struct drm_driver.gem_prime_mmap.
-
-Level: Intermediate
-
  connector register/unregister fixes
  ---
  diff --git a/drivers/accel/ivpu/ivpu_drv.c 
b/drivers/accel/ivpu/ivpu_drv.c

index 2df7643b843d5..9f2b9fdcc5498 100644
--- a/drivers/accel/ivpu/ivpu_drv.c
+++ b/drivers/accel/ivpu/ivpu_drv.c
@@ -376,7 +376,6 @@ static const struct drm_driver driver = {
  .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
  .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
  .gem_prime_import = ivpu_gem_prime_import,
-    .gem_prime_mmap = drm_gem_prime_mmap,
    .ioctls = ivpu_drm_ioctls,
  .num_ioctls = ARRAY_SIZE(ivpu_drm_ioctls),
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c

index c9a41c997c6c7..7681f79f462eb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2809,7 +2809,6 @@ static const struct drm_driver 
amdgpu_kms_driver = {

  .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
  .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
   

Re: [Freedreno] [2/2] drm: Remove struct drm_driver.gem_prime_mmap

2023-06-13 Thread Thomas Zimmermann

Hi

Am 14.06.23 um 04:06 schrieb Sui Jingfeng:


On 2023/6/14 01:27, Sui Jingfeng wrote:

Wow, so many drivers get nuked!

On 2023/6/13 22:51, Thomas Zimmermann wrote:

All drivers initialize this field with drm_gem_prime_mmap(). Call
the function directly and remove the field. Simplifies the code and
resolves a long-standing TODO item.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Alex Deucher 



I have tested this patch briefly with drm/amdgpu(RX560), Running 
glmark2, the rendered scene looks OK.


But single driver is self-sharing.  I think I should test this more 
with multiple video card.



No need to test; it's equivalent to removing a wrapper.


Yes, only msm hardware might be affected.



But new DRM (un-upstreamed) drivers cannot be compiled anymore with this 
patch applied.


This makes them all out-of-date or going to be outdated; this is 
embarrassing!


What do you mean by embarrassing? Simply rebase your driver onto the 
change and that's it. This happens regularly for out-of-tree drivers. 
But if such a driver would land before this patchset, I'd have to update 
the patchset instead.


Best regards
Thomas






---
  Documentation/gpu/todo.rst  |  9 -
  drivers/accel/ivpu/ivpu_drv.c   |  1 -
  drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  1 -
  drivers/gpu/drm/drm_fbdev_dma.c |  6 +-
  drivers/gpu/drm/drm_prime.c | 14 ++
  drivers/gpu/drm/etnaviv/etnaviv_drv.c   |  1 -
  drivers/gpu/drm/exynos/exynos_drm_drv.c |  1 -
  drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c |  1 -
  drivers/gpu/drm/lima/lima_drv.c |  1 -
  drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  1 -
  drivers/gpu/drm/msm/msm_drv.c   |  1 -
  drivers/gpu/drm/msm/msm_drv.h   |  1 -
  drivers/gpu/drm/msm/msm_gem_prime.c |  5 -
  drivers/gpu/drm/nouveau/nouveau_drm.c   |  1 -
  drivers/gpu/drm/panfrost/panfrost_drv.c |  1 -
  drivers/gpu/drm/pl111/pl111_drv.c   |  1 -
  drivers/gpu/drm/radeon/radeon_drv.c |  1 -
  drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c   |  1 -
  drivers/gpu/drm/rockchip/rockchip_drm_drv.c |  1 -
  drivers/gpu/drm/v3d/v3d_drv.c   |  1 -
  drivers/gpu/drm/virtio/virtgpu_drv.c    |  1 -
  drivers/gpu/drm/xen/xen_drm_front.c |  1 -
  include/drm/drm_drv.h   | 14 --
  include/drm/drm_gem_dma_helper.h    |  6 ++
  include/drm/drm_gem_shmem_helper.h  |  1 -
  include/drm/drm_gem_vram_helper.h   |  1 -
  26 files changed, 5 insertions(+), 69 deletions(-)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 68bdafa0284f5..ca1efad8c89c3 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -319,15 +319,6 @@ Contact: Daniel Vetter, Noralf Tronnes
    Level: Advanced
  -struct drm_gem_object_funcs

-
-GEM objects can now have a function table instead of having the 
callbacks on the
-DRM driver struct. This is now the preferred way. Callbacks in 
drivers have been

-converted, except for struct drm_driver.gem_prime_mmap.
-
-Level: Intermediate
-
  connector register/unregister fixes
  ---
  diff --git a/drivers/accel/ivpu/ivpu_drv.c 
b/drivers/accel/ivpu/ivpu_drv.c

index 2df7643b843d5..9f2b9fdcc5498 100644
--- a/drivers/accel/ivpu/ivpu_drv.c
+++ b/drivers/accel/ivpu/ivpu_drv.c
@@ -376,7 +376,6 @@ static const struct drm_driver driver = {
  .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
  .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
  .gem_prime_import = ivpu_gem_prime_import,
-    .gem_prime_mmap = drm_gem_prime_mmap,
    .ioctls = ivpu_drm_ioctls,
  .num_ioctls = ARRAY_SIZE(ivpu_drm_ioctls),
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c

index c9a41c997c6c7..7681f79f462eb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2809,7 +2809,6 @@ static const struct drm_driver 
amdgpu_kms_driver = {

  .prime_handle_to_fd = drm_gem_prime_handle_to_fd,
  .prime_fd_to_handle = drm_gem_prime_fd_to_handle,
  .gem_prime_import = amdgpu_gem_prime_import,
-    .gem_prime_mmap = drm_gem_prime_mmap,
    .name = DRIVER_NAME,
  .desc = DRIVER_DESC,
diff --git a/drivers/gpu/drm/drm_fbdev_dma.c 
b/drivers/gpu/drm/drm_fbdev_dma.c

index d86773fa8ab00..8217f1ddc0075 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -54,12 +54,8 @@ static void drm_fbdev_dma_fb_destroy(struct 
fb_info *info)
  static int drm_fbdev_dma_fb_mmap(struct fb_info *info, struct 
vm_area_struct *vma)

  {
  struct drm_fb_helper *fb_helper = info->par;
-    struct drm_device *dev = fb_helper->dev;
-
-    if 

[Freedreno] [PATCH 2/2] drm: Remove struct drm_driver.gem_prime_mmap

2023-06-13 Thread Thomas Zimmermann
All drivers initialize this field with drm_gem_prime_mmap(). Call
the function directly and remove the field. Simplifies the code and
resolves a long-standing TODO item.

Signed-off-by: Thomas Zimmermann 
---
 Documentation/gpu/todo.rst  |  9 -
 drivers/accel/ivpu/ivpu_drv.c   |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  1 -
 drivers/gpu/drm/drm_fbdev_dma.c |  6 +-
 drivers/gpu/drm/drm_prime.c | 14 ++
 drivers/gpu/drm/etnaviv/etnaviv_drv.c   |  1 -
 drivers/gpu/drm/exynos/exynos_drm_drv.c |  1 -
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c |  1 -
 drivers/gpu/drm/lima/lima_drv.c |  1 -
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  1 -
 drivers/gpu/drm/msm/msm_drv.c   |  1 -
 drivers/gpu/drm/msm/msm_drv.h   |  1 -
 drivers/gpu/drm/msm/msm_gem_prime.c |  5 -
 drivers/gpu/drm/nouveau/nouveau_drm.c   |  1 -
 drivers/gpu/drm/panfrost/panfrost_drv.c |  1 -
 drivers/gpu/drm/pl111/pl111_drv.c   |  1 -
 drivers/gpu/drm/radeon/radeon_drv.c |  1 -
 drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c   |  1 -
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |  1 -
 drivers/gpu/drm/v3d/v3d_drv.c   |  1 -
 drivers/gpu/drm/virtio/virtgpu_drv.c|  1 -
 drivers/gpu/drm/xen/xen_drm_front.c |  1 -
 include/drm/drm_drv.h   | 14 --
 include/drm/drm_gem_dma_helper.h|  6 ++
 include/drm/drm_gem_shmem_helper.h  |  1 -
 include/drm/drm_gem_vram_helper.h   |  1 -
 26 files changed, 5 insertions(+), 69 deletions(-)

diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index 68bdafa0284f5..ca1efad8c89c3 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -319,15 +319,6 @@ Contact: Daniel Vetter, Noralf Tronnes
 
 Level: Advanced
 
-struct drm_gem_object_funcs

-
-GEM objects can now have a function table instead of having the callbacks on 
the
-DRM driver struct. This is now the preferred way. Callbacks in drivers have 
been
-converted, except for struct drm_driver.gem_prime_mmap.
-
-Level: Intermediate
-
 connector register/unregister fixes
 ---
 
diff --git a/drivers/accel/ivpu/ivpu_drv.c b/drivers/accel/ivpu/ivpu_drv.c
index 2df7643b843d5..9f2b9fdcc5498 100644
--- a/drivers/accel/ivpu/ivpu_drv.c
+++ b/drivers/accel/ivpu/ivpu_drv.c
@@ -376,7 +376,6 @@ static const struct drm_driver driver = {
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = ivpu_gem_prime_import,
-   .gem_prime_mmap = drm_gem_prime_mmap,
 
.ioctls = ivpu_drm_ioctls,
.num_ioctls = ARRAY_SIZE(ivpu_drm_ioctls),
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index c9a41c997c6c7..7681f79f462eb 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -2809,7 +2809,6 @@ static const struct drm_driver amdgpu_kms_driver = {
.prime_handle_to_fd = drm_gem_prime_handle_to_fd,
.prime_fd_to_handle = drm_gem_prime_fd_to_handle,
.gem_prime_import = amdgpu_gem_prime_import,
-   .gem_prime_mmap = drm_gem_prime_mmap,
 
.name = DRIVER_NAME,
.desc = DRIVER_DESC,
diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c
index d86773fa8ab00..8217f1ddc0075 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -54,12 +54,8 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info)
 static int drm_fbdev_dma_fb_mmap(struct fb_info *info, struct vm_area_struct 
*vma)
 {
struct drm_fb_helper *fb_helper = info->par;
-   struct drm_device *dev = fb_helper->dev;
-
-   if (drm_WARN_ON_ONCE(dev, !fb_helper->dev->driver->gem_prime_mmap))
-   return -ENODEV;
 
-   return fb_helper->dev->driver->gem_prime_mmap(fb_helper->buffer->gem, 
vma);
+   return drm_gem_prime_mmap(fb_helper->buffer->gem, vma);
 }
 
 static const struct fb_ops drm_fbdev_dma_fb_ops = {
diff --git a/drivers/gpu/drm/drm_prime.c b/drivers/gpu/drm/drm_prime.c
index d29dafce9bb0a..6bcf324ef81c9 100644
--- a/drivers/gpu/drm/drm_prime.c
+++ b/drivers/gpu/drm/drm_prime.c
@@ -715,8 +715,6 @@ EXPORT_SYMBOL(drm_gem_dmabuf_vunmap);
  * the same codepath that is used for regular GEM buffer mapping on the DRM fd.
  * The fake GEM offset is added to vma->vm_pgoff and &drm_driver->fops->mmap is
  * called to set up the mapping.
- *
- * Drivers can use this as their &drm_driver.gem_prime_mmap callback.
  */
 int drm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
 {
@@ -772,25 +770,17 @@

[Freedreno] [PATCH 1/2] drm/msm: Initialize mmap offset after constructing the buffer object

2023-06-13 Thread Thomas Zimmermann
Only the msm driver provides its own implementation of gem_prime_mmap
from struct drm_driver. All other drivers use the drm_gem_prime_mmap()
helper.

Initialize the mmap offset when constructing the buffer object in msm
and reduce the gem_prime_mmap code to the generic helper. Prepares
msm for the removal of struct drm_driver.gem_prime_mmap.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/msm/msm_gem.c   |  8 
 drivers/gpu/drm/msm/msm_gem_prime.c | 10 --
 2 files changed, 8 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_gem.c b/drivers/gpu/drm/msm/msm_gem.c
index 20cfd86d2b324..635744bc4765f 100644
--- a/drivers/gpu/drm/msm/msm_gem.c
+++ b/drivers/gpu/drm/msm/msm_gem.c
@@ -1234,6 +1234,10 @@ struct drm_gem_object *msm_gem_new(struct drm_device 
*dev, uint32_t size, uint32
list_add_tail(&msm_obj->node, &priv->objects);
mutex_unlock(&priv->obj_lock);
 
+   ret = drm_gem_create_mmap_offset(obj);
+   if (ret)
+   goto fail;
+
return obj;
 
 fail:
@@ -1290,6 +1294,10 @@ struct drm_gem_object *msm_gem_import(struct drm_device 
*dev,
list_add_tail(&msm_obj->node, &priv->objects);
mutex_unlock(&priv->obj_lock);
 
+   ret = drm_gem_create_mmap_offset(obj);
+   if (ret)
+   goto fail;
+
return obj;
 
 fail:
diff --git a/drivers/gpu/drm/msm/msm_gem_prime.c 
b/drivers/gpu/drm/msm/msm_gem_prime.c
index c1d91863df055..2c846afe049e4 100644
--- a/drivers/gpu/drm/msm/msm_gem_prime.c
+++ b/drivers/gpu/drm/msm/msm_gem_prime.c
@@ -13,16 +13,6 @@
 
 int msm_gem_prime_mmap(struct drm_gem_object *obj, struct vm_area_struct *vma)
 {
-   int ret;
-
-   /* Ensure the mmap offset is initialized.  We lazily initialize it,
-* so if it has not been first mmap'd directly as a GEM object, the
-* mmap offset will not be already initialized.
-*/
-   ret = drm_gem_create_mmap_offset(obj);
-   if (ret)
-   return ret;
-
return drm_gem_prime_mmap(obj, vma);
 }
 
-- 
2.41.0



[Freedreno] [PATCH 0/2] drm: Remove gem_prime_mmap callback

2023-06-13 Thread Thomas Zimmermann
Remove the gem_prime_mmap callback from struct drm_driver. Rework
msm, which has its own implementation. Then remove the callback and
call drm_gem_prime_mmap() directly. This closes a long-standing item
on the TODO list.

The change removes the last GEM callback from the driver structure.
GEM memory managers should implement the callbacks in struct dma_buf_ops
and struct drm_gem_object_funcs to adapt the DRM to their needs.

Thomas Zimmermann (2):
  drm/msm: Initialize mmap offset after constructing the buffer object
  drm: Remove struct drm_driver.gem_prime_mmap

 Documentation/gpu/todo.rst  |  9 -
 drivers/accel/ivpu/ivpu_drv.c   |  1 -
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c |  1 -
 drivers/gpu/drm/drm_fbdev_dma.c |  6 +-
 drivers/gpu/drm/drm_prime.c | 14 ++
 drivers/gpu/drm/etnaviv/etnaviv_drv.c   |  1 -
 drivers/gpu/drm/exynos/exynos_drm_drv.c |  1 -
 drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c |  1 -
 drivers/gpu/drm/lima/lima_drv.c |  1 -
 drivers/gpu/drm/mediatek/mtk_drm_drv.c  |  1 -
 drivers/gpu/drm/msm/msm_drv.c   |  1 -
 drivers/gpu/drm/msm/msm_drv.h   |  1 -
 drivers/gpu/drm/msm/msm_gem.c   |  8 
 drivers/gpu/drm/msm/msm_gem_prime.c | 15 ---
 drivers/gpu/drm/nouveau/nouveau_drm.c   |  1 -
 drivers/gpu/drm/panfrost/panfrost_drv.c |  1 -
 drivers/gpu/drm/pl111/pl111_drv.c   |  1 -
 drivers/gpu/drm/radeon/radeon_drv.c |  1 -
 drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c   |  1 -
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c |  1 -
 drivers/gpu/drm/v3d/v3d_drv.c   |  1 -
 drivers/gpu/drm/virtio/virtgpu_drv.c|  1 -
 drivers/gpu/drm/xen/xen_drm_front.c |  1 -
 include/drm/drm_drv.h   | 14 --
 include/drm/drm_gem_dma_helper.h|  6 ++
 include/drm/drm_gem_shmem_helper.h  |  1 -
 include/drm/drm_gem_vram_helper.h   |  1 -
 27 files changed, 13 insertions(+), 79 deletions(-)


base-commit: 63a468ec7c7652afa80e3fa6ad203f9e64d04e83
-- 
2.41.0



Re: [Freedreno] [PATCH 1/2] drm/msm: provide fb_dirty implemenation

2023-06-12 Thread Thomas Zimmermann

Hi

Am 12.06.23 um 11:14 schrieb Marijn Suijten:

On 2023-06-12 06:16:15, Dmitry Baryshkov wrote:

Since commit 93e81e38e197 ("drm/fb_helper: Minimize damage-helper
overhead") the drm_fb_helper_funcs::fb_dirty helper is required for
proper dirty/damage processing. The drm/msm driver requires that to
function to let CMD panels to work. Use simplified version of
drm_fbdev_generic_helper_fb_dirty() to fix support for CMD mode panels.

Reported-by: Degdag Mohamed 
Fixes: 93e81e38e197 ("drm/fb_helper: Minimize damage-helper overhead")
Cc: Thomas Zimmermann 
Signed-off-by: Dmitry Baryshkov 


Thanks, this solves the following warning:

 msm_dpu ae01000.display-controller: 
drm_WARN_ON_ONCE(!helper->funcs->fb_dirty)
 WARNING: CPU: 0 PID: 9 at drivers/gpu/drm/drm_fb_helper.c:381 
drm_fb_helper_damage_work+0x1c0/0x20c

Reviewed-by: Marijn Suijten 

Note that drm_fb_helper_funcs documents this as "This callback is
optional": is it no longer optional, or are we enabling a damage feature
that makes it not-optional?


It is optional in the sense that most hardware and drivers don't require 
damage handling. Those that do, also require this callback.


Best regards
Thomas



- Marijn


---
  drivers/gpu/drm/msm/msm_fbdev.c | 20 
  1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index fa9c1cbffae3..b933a85420f6 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -139,8 +139,28 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
return ret;
  }
  
+static int msm_fbdev_fb_dirty(struct drm_fb_helper *helper,

+ struct drm_clip_rect *clip)
+{
+   struct drm_device *dev = helper->dev;
+   int ret;
+
+   /* Call damage handlers only if necessary */
+   if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
+   return 0;
+
+   if (helper->fb->funcs->dirty) {
+   ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1);
+   if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", 
ret))
+   return ret;
+   }
+
+   return 0;
+}
+
  static const struct drm_fb_helper_funcs msm_fb_helper_funcs = {
    .fb_probe = msm_fbdev_create,
+   .fb_dirty = msm_fbdev_fb_dirty,
  };
  
  /*

--
2.39.2



--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature
Description: OpenPGP digital signature


Re: [Freedreno] [PATCH 1/2] drm/msm: provide fb_dirty implemenation

2023-06-12 Thread Thomas Zimmermann

Hi

Am 12.06.23 um 05:16 schrieb Dmitry Baryshkov:

Since commit 93e81e38e197 ("drm/fb_helper: Minimize damage-helper
overhead") the drm_fb_helper_funcs::fb_dirty helper is required for
proper dirty/damage processing. The drm/msm driver requires that to
function to let CMD panels to work. Use simplified version of
drm_fbdev_generic_helper_fb_dirty() to fix support for CMD mode panels.

Reported-by: Degdag Mohamed 
Fixes: 93e81e38e197 ("drm/fb_helper: Minimize damage-helper overhead")
Cc: Thomas Zimmermann 
Signed-off-by: Dmitry Baryshkov 


Reviewed-by: Thomas Zimmermann 

To make mmap work correctly, you'll also need deferred I/O in the fbdev 
code. AFAICT the driver never supported that.


Best regards
Thomas


---
  drivers/gpu/drm/msm/msm_fbdev.c | 20 
  1 file changed, 20 insertions(+)

diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index fa9c1cbffae3..b933a85420f6 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -139,8 +139,28 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
return ret;
  }
  
+static int msm_fbdev_fb_dirty(struct drm_fb_helper *helper,

+ struct drm_clip_rect *clip)
+{
+   struct drm_device *dev = helper->dev;
+   int ret;
+
+   /* Call damage handlers only if necessary */
+   if (!(clip->x1 < clip->x2 && clip->y1 < clip->y2))
+   return 0;
+
+   if (helper->fb->funcs->dirty) {
+   ret = helper->fb->funcs->dirty(helper->fb, NULL, 0, 0, clip, 1);
+   if (drm_WARN_ONCE(dev, ret, "Dirty helper failed: ret=%d\n", 
ret))
+   return ret;
+   }
+
+   return 0;
+}
+
  static const struct drm_fb_helper_funcs msm_fb_helper_funcs = {
.fb_probe = msm_fbdev_create,
+   .fb_dirty = msm_fbdev_fb_dirty,
  };
  
  /*


--
Thomas Zimmermann
Graphics Driver Developer
SUSE Software Solutions Germany GmbH
Frankenstrasse 146, 90461 Nuernberg, Germany
GF: Ivo Totev, Andrew Myers, Andrew McDonald, Boudien Moerman
HRB 36809 (AG Nuernberg)


OpenPGP_signature
Description: OpenPGP digital signature


[Freedreno] [PATCH v5 09/13] drm/tegra: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Tegra does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
Cc: Thierry Reding 
Cc: Mikko Perttunen 
Cc: Jonathan Hunter 
---
 drivers/gpu/drm/tegra/Kconfig | 1 +
 drivers/gpu/drm/tegra/fbdev.c | 8 +++-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index 56453ca277c2..498313778175 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -12,6 +12,7 @@ config DRM_TEGRA
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select TEGRA_HOST1X
select INTERCONNECT
select IOMMU_IOVA
diff --git a/drivers/gpu/drm/tegra/fbdev.c b/drivers/gpu/drm/tegra/fbdev.c
index dca9eccae466..e74d9be981c7 100644
--- a/drivers/gpu/drm/tegra/fbdev.c
+++ b/drivers/gpu/drm/tegra/fbdev.c
@@ -8,6 +8,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include 
@@ -58,12 +59,9 @@ static void tegra_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops tegra_fb_ops = {
.owner = THIS_MODULE,
+   __FB_DEFAULT_SYS_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
+   __FB_DEFAULT_SYS_OPS_DRAW,
.fb_mmap = tegra_fb_mmap,
.fb_destroy = tegra_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v5 13/13] drm/i915: Implement dedicated fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Use an fbdev generator macro for
deferred I/O to create the fbdev callbacks. i915 was the only
caller of the DRM helpers, so remove them from the helper module.

i915's fbdev emulation is still incomplete as it doesn't implement
deferred I/O and damage handling for mmaped pages.

v4:
* generate deferred-I/O helpers
* use initializer macros for fb_ops
v2:
* use FB_IO_HELPERS options

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Sam Ravnborg 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: "Ville Syrjälä" 
---
 drivers/gpu/drm/Kconfig|   3 -
 drivers/gpu/drm/drm_fb_helper.c| 107 -
 drivers/gpu/drm/i915/Kconfig   |   1 +
 drivers/gpu/drm/i915/display/intel_fbdev.c |  14 +--
 include/drm/drm_fb_helper.h|  39 
 5 files changed, 9 insertions(+), 155 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 92a782827b7b..bb2e48cc6cd6 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -133,9 +133,6 @@ config DRM_FBDEV_EMULATION
bool "Enable legacy fbdev support for your modesetting driver"
depends on DRM_KMS_HELPER
depends on FB=y || FB=DRM_KMS_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 7f6e54967acb..61a5d450cc20 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -736,113 +736,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, 
struct list_head *pagerefli
 }
 EXPORT_SYMBOL(drm_fb_helper_deferred_io);
 
-/**
- * drm_fb_helper_cfb_read - Implements struct &fb_ops.fb_read for I/O memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_io_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_read);
-
-/**
- * drm_fb_helper_cfb_write - Implements struct &fb_ops.fb_write for I/O memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_io_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
-drm_rect_width(&damage_area),
-drm_rect_height(&damage_area));
-   }
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_write);
-
-/**
- * drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around cfb_fillrect implemented by fbdev core
- */
-void drm_fb_helper_cfb_fillrect(struct fb_info *info,
-   const struct fb_fillrect *rect)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   cfb_fillrect(info, rect);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, 
rect->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect);
-
-/**
- * drm_fb_helper_cfb_copyarea - wrapper around cfb_copyarea
- * @info: fbdev registered by the helper
- * @area: info about area to copy
- *
- * A wrapper around cfb_copyarea implemented by fbdev core
- */
-void drm_fb_helper_cfb_copyarea(struct fb_info *info,
-   const struct fb_copyarea *area)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   cfb_copyarea(info, area);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, area->dx, area->dy, area->width, 
area->height);
-}
-EXP

[Freedreno] [PATCH v5 08/13] drm/omapdrm: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Omapdrm does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
Cc: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/Kconfig  |  1 +
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 11 +++
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index 76ded1568bd0..b4ac76c9f31b 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -4,6 +4,7 @@ config DRM_OMAP
depends on DRM && OF
depends on ARCH_OMAP2PLUS
select DRM_KMS_HELPER
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select VIDEOMODE_HELPERS
select HDMI
default n
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index b950e93b3846..b7ccce0704a3 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -4,6 +4,8 @@
  * Author: Rob Clark 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -95,20 +97,13 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,
-
+   FB_DEFAULT_SYS_OPS,
.fb_check_var   = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_blank   = drm_fb_helper_blank,
.fb_pan_display = omap_fbdev_pan_display,
.fb_ioctl   = drm_fb_helper_ioctl,
-
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
-
.fb_destroy = omap_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v5 12/13] drm/fbdev-generic: Implement dedicated fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Use an fbdev generator macro for
deferred I/O to create the callbacks. Fbdev-generic was the
only caller of the DRM helpers, so remove them from the helper
module.

v4:
* generate deferred-I/O helpers
* use initializer macros for fb_ops
v2:
* use FB_SYS_HELPERS_DEFERRED option

Signed-off-by: Thomas Zimmermann 
Tested-by: Sui Jingfeng 
Reviewed-by: Sui Jingfeng 
---
 drivers/gpu/drm/Kconfig |   6 +-
 drivers/gpu/drm/drm_fb_helper.c | 107 
 drivers/gpu/drm/drm_fbdev_generic.c |  11 ++-
 include/drm/drm_fb_helper.h |  41 ---
 4 files changed, 6 insertions(+), 159 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 77fb10ddd8a2..92a782827b7b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -95,6 +95,7 @@ config DRM_KUNIT_TEST
 config DRM_KMS_HELPER
tristate
depends on DRM
+   select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
help
  CRTC helpers for KMS drivers.
 
@@ -135,11 +136,6 @@ config DRM_FBDEV_EMULATION
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
-   select FB_DEFERRED_IO
-   select FB_SYS_FOPS
-   select FB_SYS_FILLRECT
-   select FB_SYS_COPYAREA
-   select FB_SYS_IMAGEBLIT
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 7071c810ba83..7f6e54967acb 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -736,113 +736,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, 
struct list_head *pagerefli
 }
 EXPORT_SYMBOL(drm_fb_helper_deferred_io);
 
-/**
- * drm_fb_helper_sys_read - Implements struct &fb_ops.fb_read for system memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_sys_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_read);
-
-/**
- * drm_fb_helper_sys_write - Implements struct &fb_ops.fb_write for system 
memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_sys_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
-drm_rect_width(&damage_area),
-drm_rect_height(&damage_area));
-   }
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_write);
-
-/**
- * drm_fb_helper_sys_fillrect - wrapper around sys_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around sys_fillrect implemented by fbdev core
- */
-void drm_fb_helper_sys_fillrect(struct fb_info *info,
-   const struct fb_fillrect *rect)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_fillrect(info, rect);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, 
rect->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_fillrect);
-
-/**
- * drm_fb_helper_sys_copyarea - wrapper around sys_copyarea
- * @info: fbdev registered by the helper
- * @area: info about area to copy
- *
- * A wrapper around sys_copyarea implemented by fbdev core
- */
-void drm_fb_helper_sys_copyarea(struct fb_info *info,
-   const struct fb_copyarea *area)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_copyarea(info, area);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, area->dx, area->dy, area->width, 
area->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_copyarea);
-
-/**

[Freedreno] [PATCH v5 11/13] drm/msm: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Msm does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

Msm's fbdev emulation has been incomplete as it didn't implement
damage handling. Partilly fix this by implementing damage handling
for write and draw operation. It is still missing for mmaped pages.

v4:
* use initializer macros for struct fb_ops
* partially support damage handling
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Dmitry Baryshkov 
Acked-by: Sam Ravnborg 
Cc: Rob Clark 
Cc: Abhinav Kumar 
Cc: Dmitry Baryshkov 
Cc: Sean Paul 
---
 drivers/gpu/drm/msm/Kconfig |  1 +
 drivers/gpu/drm/msm/msm_fbdev.c | 17 -
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 85f5ab1d552c..a78662bd6273 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -21,6 +21,7 @@ config DRM_MSM
select DRM_BRIDGE
select DRM_PANEL_BRIDGE
select DRM_SCHED
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select SHMEM
select TMPFS
select QCOM_SCM
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index ce0ba6d1979a..fa9c1cbffae3 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -4,6 +4,8 @@
  * Author: Rob Clark 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -23,6 +25,10 @@ module_param(fbdev, bool, 0600);
  * fbdev funcs, to implement legacy fbdev interface on top of drm driver
  */
 
+FB_GEN_DEFAULT_DEFERRED_SYS_OPS(msm_fbdev,
+   drm_fb_helper_damage_range,
+   drm_fb_helper_damage_area)
+
 static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
@@ -52,16 +58,9 @@ static void msm_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops msm_fb_ops = {
.owner = THIS_MODULE,
+   __FB_DEFAULT_DEFERRED_OPS_RDWR(msm_fbdev),
DRM_FB_HELPER_DEFAULT_OPS,
-
-   /* Note: to properly handle manual update displays, we wrap the
-* basic fbdev ops which write to the framebuffer
-*/
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
+   __FB_DEFAULT_DEFERRED_OPS_DRAW(msm_fbdev),
.fb_mmap = msm_fbdev_mmap,
.fb_destroy = msm_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v5 06/13] drm/radeon: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Radeon does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Alex Deucher 
Acked-by: Sam Ravnborg 
Cc: Alex Deucher 
Cc: "Christian König" 
Cc: "Pan, Xinhui" 
---
 drivers/gpu/drm/radeon/Kconfig| 1 +
 drivers/gpu/drm/radeon/radeon_fbdev.c | 9 +++--
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig
index e19d77d58810..fe498c8af1bb 100644
--- a/drivers/gpu/drm/radeon/Kconfig
+++ b/drivers/gpu/drm/radeon/Kconfig
@@ -11,6 +11,7 @@ config DRM_RADEON
select DRM_SUBALLOC_HELPER
 select DRM_TTM
select DRM_TTM_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select SND_HDA_COMPONENT if SND_HDA_CORE
select POWER_SUPPLY
select HWMON
diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c 
b/drivers/gpu/drm/radeon/radeon_fbdev.c
index fe76e29910ef..28212c2d6c98 100644
--- a/drivers/gpu/drm/radeon/radeon_fbdev.c
+++ b/drivers/gpu/drm/radeon/radeon_fbdev.c
@@ -24,6 +24,7 @@
  * David Airlie
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -190,14 +191,10 @@ static void radeon_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops radeon_fbdev_fb_ops = {
.owner = THIS_MODULE,
-   DRM_FB_HELPER_DEFAULT_OPS,
.fb_open = radeon_fbdev_fb_open,
.fb_release = radeon_fbdev_fb_release,
-   .fb_read = drm_fb_helper_cfb_read,
-   .fb_write = drm_fb_helper_cfb_write,
-   .fb_fillrect = drm_fb_helper_cfb_fillrect,
-   .fb_copyarea = drm_fb_helper_cfb_copyarea,
-   .fb_imageblit = drm_fb_helper_cfb_imageblit,
+   FB_DEFAULT_IO_OPS,
+   DRM_FB_HELPER_DEFAULT_OPS,
.fb_destroy = radeon_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v5 05/13] drm/gma500: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Gma500 does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
Cc: Patrik Jakobsson 
---
 drivers/gpu/drm/gma500/Kconfig | 1 +
 drivers/gpu/drm/gma500/fbdev.c | 8 +++-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig
index 2efc0eb41c64..cd3d92725ed4 100644
--- a/drivers/gpu/drm/gma500/Kconfig
+++ b/drivers/gpu/drm/gma500/Kconfig
@@ -3,6 +3,7 @@ config DRM_GMA500
tristate "Intel GMA500/600/3600/3650 KMS Framebuffer"
depends on DRM && PCI && X86 && MMU
select DRM_KMS_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select I2C
select I2C_ALGOBIT
# GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915
diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c
index 4f0309548b2b..955cbe9f05a7 100644
--- a/drivers/gpu/drm/gma500/fbdev.c
+++ b/drivers/gpu/drm/gma500/fbdev.c
@@ -5,6 +5,7 @@
  *
  **/
 
+#include 
 #include 
 
 #include 
@@ -134,13 +135,10 @@ static void psb_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops psb_fbdev_fb_ops = {
.owner = THIS_MODULE,
+   __FB_DEFAULT_IO_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
.fb_setcolreg = psb_fbdev_fb_setcolreg,
-   .fb_read = drm_fb_helper_cfb_read,
-   .fb_write = drm_fb_helper_cfb_write,
-   .fb_fillrect = drm_fb_helper_cfb_fillrect,
-   .fb_copyarea = drm_fb_helper_cfb_copyarea,
-   .fb_imageblit = drm_fb_helper_cfb_imageblit,
+   __FB_DEFAULT_IO_OPS_DRAW,
.fb_mmap = psb_fbdev_fb_mmap,
.fb_destroy = psb_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v5 10/13] drm/fb-helper: Export helpers for marking damage areas

2023-05-30 Thread Thomas Zimmermann
Export drm_fb_helper_damage() and drm_fb_helper_damage_range(), which
handle damage areas for fbdev emulation. This is a temporary export
that allows to move the DRM I/O helpers for fbdev into drivers. Only
fbdev-generic and i915 need them. Both will be updated to implement
damage handling by themselves and the exported functions will be removed.

v4:
* update interfaces

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
---
 drivers/gpu/drm/drm_fb_helper.c | 22 ++
 include/drm/drm_fb_helper.h |  3 +++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 8dc376b771d2..7071c810ba83 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -670,6 +670,28 @@ static void drm_fb_helper_memory_range_to_clip(struct 
fb_info *info, off_t off,
drm_rect_init(clip, x1, y1, x2 - x1, y2 - y1);
 }
 
+/* Don't use in new code. */
+void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+   struct drm_rect damage_area;
+
+   drm_fb_helper_memory_range_to_clip(info, off, len, &damage_area);
+   drm_fb_helper_damage(fb_helper, damage_area.x1, damage_area.y1,
+drm_rect_width(&damage_area),
+drm_rect_height(&damage_area));
+}
+EXPORT_SYMBOL(drm_fb_helper_damage_range);
+
+/* Don't use in new code. */
+void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, 
u32 height)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+
+   drm_fb_helper_damage(fb_helper, x, y, width, height);
+}
+EXPORT_SYMBOL(drm_fb_helper_damage_area);
+
 /**
  * drm_fb_helper_deferred_io() - fbdev deferred_io callback function
  * @info: fb_info struct pointer
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 72032c354a30..7d5804882be7 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -253,6 +253,9 @@ void drm_fb_helper_fill_info(struct fb_info *info,
 struct drm_fb_helper *fb_helper,
 struct drm_fb_helper_surface_size *sizes);
 
+void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len);
+void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, 
u32 height);
+
 void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head 
*pagereflist);
 
 ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-- 
2.40.1



[Freedreno] [PATCH v5 03/13] drm/armada: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Armada does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
Cc: Russell King 
---
 drivers/gpu/drm/armada/Kconfig| 1 +
 drivers/gpu/drm/armada/armada_fbdev.c | 7 ++-
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig
index f5c66d89ba99..5afade25e217 100644
--- a/drivers/gpu/drm/armada/Kconfig
+++ b/drivers/gpu/drm/armada/Kconfig
@@ -3,6 +3,7 @@ config DRM_ARMADA
tristate "DRM support for Marvell Armada SoCs"
depends on DRM && HAVE_CLK && ARM && MMU
select DRM_KMS_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
help
  Support the "LCD" controllers found on the Marvell Armada 510
  devices.  There are two controllers on the device, each controller
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c 
b/drivers/gpu/drm/armada/armada_fbdev.c
index 0a5fd1aa86eb..3943e89cc06c 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
@@ -33,12 +34,8 @@ static void armada_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops armada_fb_ops = {
.owner  = THIS_MODULE,
+   FB_DEFAULT_IO_OPS,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_read= drm_fb_helper_cfb_read,
-   .fb_write   = drm_fb_helper_cfb_write,
-   .fb_fillrect= drm_fb_helper_cfb_fillrect,
-   .fb_copyarea= drm_fb_helper_cfb_copyarea,
-   .fb_imageblit   = drm_fb_helper_cfb_imageblit,
.fb_destroy = armada_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v5 04/13] drm/exynos: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Exynos does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v3:
* don't reorder Makefile rules (Sam)
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
Cc: Inki Dae 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Krzysztof Kozlowski 
Cc: Alim Akhtar 
---
 drivers/gpu/drm/exynos/Kconfig| 1 +
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 9 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 0cb92d651ff1..7ca7e1dab52c 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -7,6 +7,7 @@ config DRM_EXYNOS
select DRM_DISPLAY_HELPER if DRM_EXYNOS_DP
select DRM_KMS_HELPER
select VIDEOMODE_HELPERS
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select SND_SOC_HDMI_CODEC if SND_SOC
help
  Choose this option if you have a Samsung SoC Exynos chipset.
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index ea4b3d248aac..fdf65587f1fe 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -8,6 +8,8 @@
  * Seung-Woo Kim 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -47,13 +49,10 @@ static void exynos_drm_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops exynos_drm_fb_ops = {
.owner  = THIS_MODULE,
+   __FB_DEFAULT_IO_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
+   __FB_DEFAULT_IO_OPS_DRAW,
.fb_mmap= exynos_drm_fb_mmap,
-   .fb_read= drm_fb_helper_cfb_read,
-   .fb_write   = drm_fb_helper_cfb_write,
-   .fb_fillrect= drm_fb_helper_cfb_fillrect,
-   .fb_copyarea= drm_fb_helper_cfb_copyarea,
-   .fb_imageblit   = drm_fb_helper_cfb_imageblit,
.fb_destroy = exynos_drm_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v5 01/13] fbdev: Add Kconfig options to select different fb_ops helpers

2023-05-30 Thread Thomas Zimmermann
Many fbdev drivers use the same set of fb_ops helpers. Add Kconfig
options to select them at once. This will help with making DRM's
fbdev emulation code more modular, but can also be used to simplify
fbdev's driver configs.

v3:
* fix select statement (Jingfeng)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Sui Jingfeng 
Reviewed-by: Sam Ravnborg 
---
 drivers/video/fbdev/Kconfig | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index e8889035c882..6df9bd09454a 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -158,6 +158,27 @@ config FB_DEFERRED_IO
bool
depends on FB
 
+config FB_IO_HELPERS
+   bool
+   depends on FB
+   select FB_CFB_COPYAREA
+   select FB_CFB_FILLRECT
+   select FB_CFB_IMAGEBLIT
+
+config FB_SYS_HELPERS
+   bool
+   depends on FB
+   select FB_SYS_COPYAREA
+   select FB_SYS_FILLRECT
+   select FB_SYS_FOPS
+   select FB_SYS_IMAGEBLIT
+
+config FB_SYS_HELPERS_DEFERRED
+   bool
+   depends on FB
+   select FB_DEFERRED_IO
+   select FB_SYS_HELPERS
+
 config FB_HECUBA
tristate
depends on FB
-- 
2.40.1



[Freedreno] [PATCH v5 02/13] fbdev: Add initializer macros for struct fb_ops

2023-05-30 Thread Thomas Zimmermann
For framebuffers in I/O and system memory, add macros that set
struct fb_ops to the respective callback functions.

For deferred I/O, add macros that generate callback functions with
damage handling. Add initializer macros that set struct fb_ops to
the generated callbacks.

These macros can remove a lot boilerplate code from fbdev drivers.
The drivers are supposed to use the macro that is required for its
framebuffer. Each macro is split into smaller helpers, so that
drivers with non-standard callbacks can pick and customize callbacks
as needed. There are individual helper macros for read/write, mmap
and drawing.

v5:
* fix whitespace errors (Jingfeng)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Sam Ravnborg 
---
 include/linux/fb.h | 112 +
 1 file changed, 112 insertions(+)

diff --git a/include/linux/fb.h b/include/linux/fb.h
index 2cf8efcb9e32..ce6823e157e6 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -538,9 +538,31 @@ extern ssize_t fb_io_read(struct fb_info *info, char 
__user *buf,
 extern ssize_t fb_io_write(struct fb_info *info, const char __user *buf,
   size_t count, loff_t *ppos);
 
+/*
+ * Initializes struct fb_ops for framebuffers in I/O memory.
+ */
+
+#define __FB_DEFAULT_IO_OPS_RDWR \
+   .fb_read= fb_io_read, \
+   .fb_write   = fb_io_write
+
+#define __FB_DEFAULT_IO_OPS_DRAW \
+   .fb_fillrect= cfb_fillrect, \
+   .fb_copyarea= cfb_copyarea, \
+   .fb_imageblit   = cfb_imageblit
+
+#define __FB_DEFAULT_IO_OPS_MMAP \
+   .fb_mmap= NULL // default implementation
+
+#define FB_DEFAULT_IO_OPS \
+   __FB_DEFAULT_IO_OPS_RDWR, \
+   __FB_DEFAULT_IO_OPS_DRAW, \
+   __FB_DEFAULT_IO_OPS_MMAP
+
 /*
  * Drawing operations where framebuffer is in system RAM
  */
+
 extern void sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
 extern void sys_copyarea(struct fb_info *info, const struct fb_copyarea *area);
 extern void sys_imageblit(struct fb_info *info, const struct fb_image *image);
@@ -549,6 +571,27 @@ extern ssize_t fb_sys_read(struct fb_info *info, char 
__user *buf,
 extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
 
+/*
+ * Initializes struct fb_ops for framebuffers in system memory.
+ */
+
+#define __FB_DEFAULT_SYS_OPS_RDWR \
+   .fb_read= fb_sys_read, \
+   .fb_write   = fb_sys_write
+
+#define __FB_DEFAULT_SYS_OPS_DRAW \
+   .fb_fillrect= sys_fillrect, \
+   .fb_copyarea= sys_copyarea, \
+   .fb_imageblit   = sys_imageblit
+
+#define __FB_DEFAULT_SYS_OPS_MMAP \
+   .fb_mmap= NULL // default implementation
+
+#define FB_DEFAULT_SYS_OPS \
+   __FB_DEFAULT_SYS_OPS_RDWR, \
+   __FB_DEFAULT_SYS_OPS_DRAW, \
+   __FB_DEFAULT_SYS_OPS_MMAP
+
 /* drivers/video/fbmem.c */
 extern int register_framebuffer(struct fb_info *fb_info);
 extern void unregister_framebuffer(struct fb_info *fb_info);
@@ -604,6 +647,75 @@ extern void fb_deferred_io_cleanup(struct fb_info *info);
 extern int fb_deferred_io_fsync(struct file *file, loff_t start,
loff_t end, int datasync);
 
+/*
+ * Generate callbacks for deferred I/O
+ */
+
+#define __FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, __mode) \
+   static ssize_t __prefix ## _defio_read(struct fb_info *info, char 
__user *buf, \
+  size_t count, loff_t *ppos) \
+   { \
+   return fb_ ## __mode ## _read(info, buf, count, ppos); \
+   } \
+   static ssize_t __prefix ## _defio_write(struct fb_info *info, const 
char __user *buf, \
+   size_t count, loff_t *ppos) \
+   { \
+   unsigned long offset = *ppos; \
+   ssize_t ret = fb_ ## __mode ## _write(info, buf, count, ppos); \
+   if (ret > 0) \
+   __damage_range(info, offset, ret); \
+   return ret; \
+   }
+
+#define __FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, __mode) \
+   static void __prefix ## _defio_fillrect(struct fb_info *info, \
+   const struct fb_fillrect *rect) 
\
+   { \
+   __mode ## _fillrect(info, rect); \
+   __damage_area(info, rect->dx, rect->dy, rect->width, 
rect->height); \
+   } \
+   static void __prefix ## _defio_copyarea(struct fb_info *info, \
+   const struct fb_copyarea *area) 
\
+   { \
+   __mode ## _copyarea(info, area); \
+   __damage_area(info, area->dx, area->dy, area->width, 
area->height); \
+   } \
+   static void __prefix ## _defio_imageblit(struct fb_info *info, \
+c

[Freedreno] [PATCH v5 07/13] drm/fbdev-dma: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Fbdev-dma does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
---
 drivers/gpu/drm/Kconfig |  1 +
 drivers/gpu/drm/drm_fbdev_dma.c | 11 +--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index ba3fb04bb691..77fb10ddd8a2 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -223,6 +223,7 @@ config DRM_TTM_HELPER
 config DRM_GEM_DMA_HELPER
tristate
depends on DRM
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
help
  Choose this if you need the GEM DMA helper functions
 
diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c
index 728deffcc0d9..d86773fa8ab0 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: MIT
 
+#include 
+
 #include 
 #include 
 #include 
@@ -64,14 +66,11 @@ static const struct fb_ops drm_fbdev_dma_fb_ops = {
.owner = THIS_MODULE,
.fb_open = drm_fbdev_dma_fb_open,
.fb_release = drm_fbdev_dma_fb_release,
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
+   __FB_DEFAULT_SYS_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
-   .fb_destroy = drm_fbdev_dma_fb_destroy,
+   __FB_DEFAULT_SYS_OPS_DRAW,
.fb_mmap = drm_fbdev_dma_fb_mmap,
+   .fb_destroy = drm_fbdev_dma_fb_destroy,
 };
 
 /*
-- 
2.40.1



[Freedreno] [PATCH v5 00/13] drm/fbdev: Remove DRM's helpers for fbdev I/O

2023-05-30 Thread Thomas Zimmermann
DRM provides a number of wrappers around fbdev cfb_() sys_(), fb_io_()
and fb_sys_() helpers. The DRM functions don't provide any additional
functionality for most DRM drivers. So remove them and call the fbdev
I/O helpers directly.

The DRM fbdev I/O wrappers were originally added because 
does not protect its content with CONFIG_FB. DRM fbdev emulation did
not build if the config option had been disabled. This has been
fixed. For fbdev-generic and i915, the wrappers added support for damage
handling. But this is better handled within the two callers, as each
is special in its damage handling.

Patch 1 adds several internal Kconfig options that DRM drivers (and
possibly other fbdev code) will use to select the correct set of I/O
helpers. Patch 2 adds initializers for struct fb_ops and generator
macros for the callback functions. These macros will simplify drivers.
This patchset applies the new options and macros to DRM fbdev emulation,
but regular fbdev drivers can use them as well.

Patches 3 to 9 replace the DRM wrappers in a number of fbdev emulations.
Patch 10 exports two helpers for damage handling. Patches 11 to 13
update msm, fbdev-generic and i915 with the help of the exported functions.
The patches also remove DRM's fbdev I/O helpers, which are now unused.

DRM's fbdev helpers had to select fbdev I/O helpers for I/O and for
system memory. Each fbdev emulation now selects the correct helpers
for itself. Depending on the selected DRM drivers, kernel builds will
now only contain the necessary fbdev I/O helpers and might be slightly
smaller in size.

v5:
* fix whitespace errors (Jingfeng)
* move msm patch to later position make it build
v4:
* use initializer and generator macros for struct fb_ops
* partially support damage handling in msm (Dmitri)
v3:
* fix Kconfig options (Jingfeng)
* minimize changes to exynos (Sam)
v2:
* simplify Kconfig handling (Sam)

Thomas Zimmermann (13):
  fbdev: Add Kconfig options to select different fb_ops helpers
  fbdev: Add initializer macros for struct fb_ops
  drm/armada: Use regular fbdev I/O helpers
  drm/exynos: Use regular fbdev I/O helpers
  drm/gma500: Use regular fbdev I/O helpers
  drm/radeon: Use regular fbdev I/O helpers
  drm/fbdev-dma: Use regular fbdev I/O helpers
  drm/omapdrm: Use regular fbdev I/O helpers
  drm/tegra: Use regular fbdev I/O helpers
  drm/fb-helper: Export helpers for marking damage areas
  drm/msm: Use regular fbdev I/O helpers
  drm/fbdev-generic: Implement dedicated fbdev I/O helpers
  drm/i915: Implement dedicated fbdev I/O helpers

 drivers/gpu/drm/Kconfig|  10 +-
 drivers/gpu/drm/armada/Kconfig |   1 +
 drivers/gpu/drm/armada/armada_fbdev.c  |   7 +-
 drivers/gpu/drm/drm_fb_helper.c| 236 ++---
 drivers/gpu/drm/drm_fbdev_dma.c|  11 +-
 drivers/gpu/drm/drm_fbdev_generic.c|  11 +-
 drivers/gpu/drm/exynos/Kconfig |   1 +
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |   9 +-
 drivers/gpu/drm/gma500/Kconfig |   1 +
 drivers/gpu/drm/gma500/fbdev.c |   8 +-
 drivers/gpu/drm/i915/Kconfig   |   1 +
 drivers/gpu/drm/i915/display/intel_fbdev.c |  14 +-
 drivers/gpu/drm/msm/Kconfig|   1 +
 drivers/gpu/drm/msm/msm_fbdev.c|  17 +-
 drivers/gpu/drm/omapdrm/Kconfig|   1 +
 drivers/gpu/drm/omapdrm/omap_fbdev.c   |  11 +-
 drivers/gpu/drm/radeon/Kconfig |   1 +
 drivers/gpu/drm/radeon/radeon_fbdev.c  |   9 +-
 drivers/gpu/drm/tegra/Kconfig  |   1 +
 drivers/gpu/drm/tegra/fbdev.c  |   8 +-
 drivers/video/fbdev/Kconfig|  21 ++
 include/drm/drm_fb_helper.h|  83 +---
 include/linux/fb.h | 112 ++
 23 files changed, 212 insertions(+), 363 deletions(-)


base-commit: cf59b48ea3c0c0075d7c4e8538177d38999da7b0
prerequisite-patch-id: 0aa359f6144c4015c140c8a6750be19099c676fb
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
prerequisite-patch-id: cbc453ee02fae02af22fbfdce56ab732c7a88c36
-- 
2.40.1



[Freedreno] [PATCH v5 13/13] drm/i915: Implement dedicated fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Use an fbdev generator macro for
deferred I/O to create the fbdev callbacks. i915 was the only
caller of the DRM helpers, so remove them from the helper module.

i915's fbdev emulation is still incomplete as it doesn't implement
deferred I/O and damage handling for mmaped pages.

v4:
* generate deferred-I/O helpers
* use initializer macros for fb_ops
v2:
* use FB_IO_HELPERS options

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Sam Ravnborg 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: "Ville Syrjälä" 
---
 drivers/gpu/drm/Kconfig|   3 -
 drivers/gpu/drm/drm_fb_helper.c| 107 -
 drivers/gpu/drm/i915/Kconfig   |   1 +
 drivers/gpu/drm/i915/display/intel_fbdev.c |  14 +--
 include/drm/drm_fb_helper.h|  39 
 5 files changed, 9 insertions(+), 155 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 92a782827b7b..bb2e48cc6cd6 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -133,9 +133,6 @@ config DRM_FBDEV_EMULATION
bool "Enable legacy fbdev support for your modesetting driver"
depends on DRM_KMS_HELPER
depends on FB=y || FB=DRM_KMS_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 7f6e54967acb..61a5d450cc20 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -736,113 +736,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, 
struct list_head *pagerefli
 }
 EXPORT_SYMBOL(drm_fb_helper_deferred_io);
 
-/**
- * drm_fb_helper_cfb_read - Implements struct &fb_ops.fb_read for I/O memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_io_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_read);
-
-/**
- * drm_fb_helper_cfb_write - Implements struct &fb_ops.fb_write for I/O memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_io_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
-drm_rect_width(&damage_area),
-drm_rect_height(&damage_area));
-   }
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_write);
-
-/**
- * drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around cfb_fillrect implemented by fbdev core
- */
-void drm_fb_helper_cfb_fillrect(struct fb_info *info,
-   const struct fb_fillrect *rect)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   cfb_fillrect(info, rect);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, 
rect->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect);
-
-/**
- * drm_fb_helper_cfb_copyarea - wrapper around cfb_copyarea
- * @info: fbdev registered by the helper
- * @area: info about area to copy
- *
- * A wrapper around cfb_copyarea implemented by fbdev core
- */
-void drm_fb_helper_cfb_copyarea(struct fb_info *info,
-   const struct fb_copyarea *area)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   cfb_copyarea(info, area);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, area->dx, area->dy, area->width, 
area->height);
-}
-EXP

[Freedreno] [PATCH v5 12/13] drm/fbdev-generic: Implement dedicated fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Use an fbdev generator macro for
deferred I/O to create the callbacks. Fbdev-generic was the
only caller of the DRM helpers, so remove them from the helper
module.

v4:
* generate deferred-I/O helpers
* use initializer macros for fb_ops
v2:
* use FB_SYS_HELPERS_DEFERRED option

Signed-off-by: Thomas Zimmermann 
Tested-by: Sui Jingfeng 
Reviewed-by: Sui Jingfeng 
---
 drivers/gpu/drm/Kconfig |   6 +-
 drivers/gpu/drm/drm_fb_helper.c | 107 
 drivers/gpu/drm/drm_fbdev_generic.c |  11 ++-
 include/drm/drm_fb_helper.h |  41 ---
 4 files changed, 6 insertions(+), 159 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 77fb10ddd8a2..92a782827b7b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -95,6 +95,7 @@ config DRM_KUNIT_TEST
 config DRM_KMS_HELPER
tristate
depends on DRM
+   select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
help
  CRTC helpers for KMS drivers.
 
@@ -135,11 +136,6 @@ config DRM_FBDEV_EMULATION
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
-   select FB_DEFERRED_IO
-   select FB_SYS_FOPS
-   select FB_SYS_FILLRECT
-   select FB_SYS_COPYAREA
-   select FB_SYS_IMAGEBLIT
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 7071c810ba83..7f6e54967acb 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -736,113 +736,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, 
struct list_head *pagerefli
 }
 EXPORT_SYMBOL(drm_fb_helper_deferred_io);
 
-/**
- * drm_fb_helper_sys_read - Implements struct &fb_ops.fb_read for system memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_sys_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_read);
-
-/**
- * drm_fb_helper_sys_write - Implements struct &fb_ops.fb_write for system 
memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_sys_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
-drm_rect_width(&damage_area),
-drm_rect_height(&damage_area));
-   }
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_write);
-
-/**
- * drm_fb_helper_sys_fillrect - wrapper around sys_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around sys_fillrect implemented by fbdev core
- */
-void drm_fb_helper_sys_fillrect(struct fb_info *info,
-   const struct fb_fillrect *rect)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_fillrect(info, rect);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, 
rect->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_fillrect);
-
-/**
- * drm_fb_helper_sys_copyarea - wrapper around sys_copyarea
- * @info: fbdev registered by the helper
- * @area: info about area to copy
- *
- * A wrapper around sys_copyarea implemented by fbdev core
- */
-void drm_fb_helper_sys_copyarea(struct fb_info *info,
-   const struct fb_copyarea *area)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_copyarea(info, area);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, area->dx, area->dy, area->width, 
area->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_copyarea);
-
-/**

[Freedreno] [PATCH v5 10/13] drm/fb-helper: Export helpers for marking damage areas

2023-05-30 Thread Thomas Zimmermann
Export drm_fb_helper_damage() and drm_fb_helper_damage_range(), which
handle damage areas for fbdev emulation. This is a temporary export
that allows to move the DRM I/O helpers for fbdev into drivers. Only
fbdev-generic and i915 need them. Both will be updated to implement
damage handling by themselves and the exported functions will be removed.

v4:
* update interfaces

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
---
 drivers/gpu/drm/drm_fb_helper.c | 22 ++
 include/drm/drm_fb_helper.h |  3 +++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 8dc376b771d2..7071c810ba83 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -670,6 +670,28 @@ static void drm_fb_helper_memory_range_to_clip(struct 
fb_info *info, off_t off,
drm_rect_init(clip, x1, y1, x2 - x1, y2 - y1);
 }
 
+/* Don't use in new code. */
+void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+   struct drm_rect damage_area;
+
+   drm_fb_helper_memory_range_to_clip(info, off, len, &damage_area);
+   drm_fb_helper_damage(fb_helper, damage_area.x1, damage_area.y1,
+drm_rect_width(&damage_area),
+drm_rect_height(&damage_area));
+}
+EXPORT_SYMBOL(drm_fb_helper_damage_range);
+
+/* Don't use in new code. */
+void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, 
u32 height)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+
+   drm_fb_helper_damage(fb_helper, x, y, width, height);
+}
+EXPORT_SYMBOL(drm_fb_helper_damage_area);
+
 /**
  * drm_fb_helper_deferred_io() - fbdev deferred_io callback function
  * @info: fb_info struct pointer
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 72032c354a30..7d5804882be7 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -253,6 +253,9 @@ void drm_fb_helper_fill_info(struct fb_info *info,
 struct drm_fb_helper *fb_helper,
 struct drm_fb_helper_surface_size *sizes);
 
+void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len);
+void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, 
u32 height);
+
 void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head 
*pagereflist);
 
 ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-- 
2.40.1



[Freedreno] [PATCH v5 11/13] drm/msm: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Msm does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

Msm's fbdev emulation has been incomplete as it didn't implement
damage handling. Partilly fix this by implementing damage handling
for write and draw operation. It is still missing for mmaped pages.

v4:
* use initializer macros for struct fb_ops
* partially support damage handling
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Dmitry Baryshkov 
Acked-by: Sam Ravnborg 
Cc: Rob Clark 
Cc: Abhinav Kumar 
Cc: Dmitry Baryshkov 
Cc: Sean Paul 
---
 drivers/gpu/drm/msm/Kconfig |  1 +
 drivers/gpu/drm/msm/msm_fbdev.c | 17 -
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 85f5ab1d552c..a78662bd6273 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -21,6 +21,7 @@ config DRM_MSM
select DRM_BRIDGE
select DRM_PANEL_BRIDGE
select DRM_SCHED
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select SHMEM
select TMPFS
select QCOM_SCM
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index ce0ba6d1979a..fa9c1cbffae3 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -4,6 +4,8 @@
  * Author: Rob Clark 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -23,6 +25,10 @@ module_param(fbdev, bool, 0600);
  * fbdev funcs, to implement legacy fbdev interface on top of drm driver
  */
 
+FB_GEN_DEFAULT_DEFERRED_SYS_OPS(msm_fbdev,
+   drm_fb_helper_damage_range,
+   drm_fb_helper_damage_area)
+
 static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
@@ -52,16 +58,9 @@ static void msm_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops msm_fb_ops = {
.owner = THIS_MODULE,
+   __FB_DEFAULT_DEFERRED_OPS_RDWR(msm_fbdev),
DRM_FB_HELPER_DEFAULT_OPS,
-
-   /* Note: to properly handle manual update displays, we wrap the
-* basic fbdev ops which write to the framebuffer
-*/
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
+   __FB_DEFAULT_DEFERRED_OPS_DRAW(msm_fbdev),
.fb_mmap = msm_fbdev_mmap,
.fb_destroy = msm_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v5 03/13] drm/armada: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Armada does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
Cc: Russell King 
---
 drivers/gpu/drm/armada/Kconfig| 1 +
 drivers/gpu/drm/armada/armada_fbdev.c | 7 ++-
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig
index f5c66d89ba99..5afade25e217 100644
--- a/drivers/gpu/drm/armada/Kconfig
+++ b/drivers/gpu/drm/armada/Kconfig
@@ -3,6 +3,7 @@ config DRM_ARMADA
tristate "DRM support for Marvell Armada SoCs"
depends on DRM && HAVE_CLK && ARM && MMU
select DRM_KMS_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
help
  Support the "LCD" controllers found on the Marvell Armada 510
  devices.  There are two controllers on the device, each controller
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c 
b/drivers/gpu/drm/armada/armada_fbdev.c
index 0a5fd1aa86eb..3943e89cc06c 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
@@ -33,12 +34,8 @@ static void armada_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops armada_fb_ops = {
.owner  = THIS_MODULE,
+   FB_DEFAULT_IO_OPS,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_read= drm_fb_helper_cfb_read,
-   .fb_write   = drm_fb_helper_cfb_write,
-   .fb_fillrect= drm_fb_helper_cfb_fillrect,
-   .fb_copyarea= drm_fb_helper_cfb_copyarea,
-   .fb_imageblit   = drm_fb_helper_cfb_imageblit,
.fb_destroy = armada_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v5 08/13] drm/omapdrm: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Omapdrm does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
Cc: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/Kconfig  |  1 +
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 11 +++
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index 76ded1568bd0..b4ac76c9f31b 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -4,6 +4,7 @@ config DRM_OMAP
depends on DRM && OF
depends on ARCH_OMAP2PLUS
select DRM_KMS_HELPER
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select VIDEOMODE_HELPERS
select HDMI
default n
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index b950e93b3846..b7ccce0704a3 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -4,6 +4,8 @@
  * Author: Rob Clark 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -95,20 +97,13 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,
-
+   FB_DEFAULT_SYS_OPS,
.fb_check_var   = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_blank   = drm_fb_helper_blank,
.fb_pan_display = omap_fbdev_pan_display,
.fb_ioctl   = drm_fb_helper_ioctl,
-
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
-
.fb_destroy = omap_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v5 09/13] drm/tegra: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Tegra does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
Cc: Thierry Reding 
Cc: Mikko Perttunen 
Cc: Jonathan Hunter 
---
 drivers/gpu/drm/tegra/Kconfig | 1 +
 drivers/gpu/drm/tegra/fbdev.c | 8 +++-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index 56453ca277c2..498313778175 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -12,6 +12,7 @@ config DRM_TEGRA
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select TEGRA_HOST1X
select INTERCONNECT
select IOMMU_IOVA
diff --git a/drivers/gpu/drm/tegra/fbdev.c b/drivers/gpu/drm/tegra/fbdev.c
index dca9eccae466..e74d9be981c7 100644
--- a/drivers/gpu/drm/tegra/fbdev.c
+++ b/drivers/gpu/drm/tegra/fbdev.c
@@ -8,6 +8,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include 
@@ -58,12 +59,9 @@ static void tegra_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops tegra_fb_ops = {
.owner = THIS_MODULE,
+   __FB_DEFAULT_SYS_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
+   __FB_DEFAULT_SYS_OPS_DRAW,
.fb_mmap = tegra_fb_mmap,
.fb_destroy = tegra_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v5 07/13] drm/fbdev-dma: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Fbdev-dma does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
---
 drivers/gpu/drm/Kconfig |  1 +
 drivers/gpu/drm/drm_fbdev_dma.c | 11 +--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index ba3fb04bb691..77fb10ddd8a2 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -223,6 +223,7 @@ config DRM_TTM_HELPER
 config DRM_GEM_DMA_HELPER
tristate
depends on DRM
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
help
  Choose this if you need the GEM DMA helper functions
 
diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c
index 728deffcc0d9..d86773fa8ab0 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: MIT
 
+#include 
+
 #include 
 #include 
 #include 
@@ -64,14 +66,11 @@ static const struct fb_ops drm_fbdev_dma_fb_ops = {
.owner = THIS_MODULE,
.fb_open = drm_fbdev_dma_fb_open,
.fb_release = drm_fbdev_dma_fb_release,
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
+   __FB_DEFAULT_SYS_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
-   .fb_destroy = drm_fbdev_dma_fb_destroy,
+   __FB_DEFAULT_SYS_OPS_DRAW,
.fb_mmap = drm_fbdev_dma_fb_mmap,
+   .fb_destroy = drm_fbdev_dma_fb_destroy,
 };
 
 /*
-- 
2.40.1



[Freedreno] [PATCH v5 06/13] drm/radeon: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Radeon does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Alex Deucher 
Acked-by: Sam Ravnborg 
Cc: Alex Deucher 
Cc: "Christian König" 
Cc: "Pan, Xinhui" 
---
 drivers/gpu/drm/radeon/Kconfig| 1 +
 drivers/gpu/drm/radeon/radeon_fbdev.c | 9 +++--
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig
index e19d77d58810..fe498c8af1bb 100644
--- a/drivers/gpu/drm/radeon/Kconfig
+++ b/drivers/gpu/drm/radeon/Kconfig
@@ -11,6 +11,7 @@ config DRM_RADEON
select DRM_SUBALLOC_HELPER
 select DRM_TTM
select DRM_TTM_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select SND_HDA_COMPONENT if SND_HDA_CORE
select POWER_SUPPLY
select HWMON
diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c 
b/drivers/gpu/drm/radeon/radeon_fbdev.c
index fe76e29910ef..28212c2d6c98 100644
--- a/drivers/gpu/drm/radeon/radeon_fbdev.c
+++ b/drivers/gpu/drm/radeon/radeon_fbdev.c
@@ -24,6 +24,7 @@
  * David Airlie
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -190,14 +191,10 @@ static void radeon_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops radeon_fbdev_fb_ops = {
.owner = THIS_MODULE,
-   DRM_FB_HELPER_DEFAULT_OPS,
.fb_open = radeon_fbdev_fb_open,
.fb_release = radeon_fbdev_fb_release,
-   .fb_read = drm_fb_helper_cfb_read,
-   .fb_write = drm_fb_helper_cfb_write,
-   .fb_fillrect = drm_fb_helper_cfb_fillrect,
-   .fb_copyarea = drm_fb_helper_cfb_copyarea,
-   .fb_imageblit = drm_fb_helper_cfb_imageblit,
+   FB_DEFAULT_IO_OPS,
+   DRM_FB_HELPER_DEFAULT_OPS,
.fb_destroy = radeon_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v5 05/13] drm/gma500: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Gma500 does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
Cc: Patrik Jakobsson 
---
 drivers/gpu/drm/gma500/Kconfig | 1 +
 drivers/gpu/drm/gma500/fbdev.c | 8 +++-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig
index 2efc0eb41c64..cd3d92725ed4 100644
--- a/drivers/gpu/drm/gma500/Kconfig
+++ b/drivers/gpu/drm/gma500/Kconfig
@@ -3,6 +3,7 @@ config DRM_GMA500
tristate "Intel GMA500/600/3600/3650 KMS Framebuffer"
depends on DRM && PCI && X86 && MMU
select DRM_KMS_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select I2C
select I2C_ALGOBIT
# GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915
diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c
index 4f0309548b2b..955cbe9f05a7 100644
--- a/drivers/gpu/drm/gma500/fbdev.c
+++ b/drivers/gpu/drm/gma500/fbdev.c
@@ -5,6 +5,7 @@
  *
  **/
 
+#include 
 #include 
 
 #include 
@@ -134,13 +135,10 @@ static void psb_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops psb_fbdev_fb_ops = {
.owner = THIS_MODULE,
+   __FB_DEFAULT_IO_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
.fb_setcolreg = psb_fbdev_fb_setcolreg,
-   .fb_read = drm_fb_helper_cfb_read,
-   .fb_write = drm_fb_helper_cfb_write,
-   .fb_fillrect = drm_fb_helper_cfb_fillrect,
-   .fb_copyarea = drm_fb_helper_cfb_copyarea,
-   .fb_imageblit = drm_fb_helper_cfb_imageblit,
+   __FB_DEFAULT_IO_OPS_DRAW,
.fb_mmap = psb_fbdev_fb_mmap,
.fb_destroy = psb_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v5 00/13]

2023-05-30 Thread Thomas Zimmermann
DRM provides a number of wrappers around fbdev cfb_() sys_(), fb_io_()
and fb_sys_() helpers. The DRM functions don't provide any additional
functionality for most DRM drivers. So remove them and call the fbdev
I/O helpers directly.

The DRM fbdev I/O wrappers were originally added because 
does not protect its content with CONFIG_FB. DRM fbdev emulation did
not build if the config option had been disabled. This has been
fixed. For fbdev-generic and i915, the wrappers added support for damage
handling. But this is better handled within the two callers, as each
is special in its damage handling.

Patch 1 adds several internal Kconfig options that DRM drivers (and
possibly other fbdev code) will use to select the correct set of I/O
helpers. Patch 2 adds initializers for struct fb_ops and generator
macros for the callback functions. These macros will simplify drivers.
This patchset applies the new options and macros to DRM fbdev emulation,
but regular fbdev drivers can use them as well.

Patches 3 to 9 replace the DRM wrappers in a number of fbdev emulations.
Patch 10 exports two helpers for damage handling. Patches 11 to 13
update msm, fbdev-generic and i915 with the help of the exported functions.
The patches also remove DRM's fbdev I/O helpers, which are now unused.

DRM's fbdev helpers had to select fbdev I/O helpers for I/O and for
system memory. Each fbdev emulation now selects the correct helpers
for itself. Depending on the selected DRM drivers, kernel builds will
now only contain the necessary fbdev I/O helpers and might be slightly
smaller in size.

v5:
* fix whitespace errors (Jingfeng)
* move msm patch to later position make it build
v4:
* use initializer and generator macros for struct fb_ops
* partially support damage handling in msm (Dmitri)
v3:
* fix Kconfig options (Jingfeng)
* minimize changes to exynos (Sam)
v2:
* simplify Kconfig handling (Sam)

Thomas Zimmermann (13):
  fbdev: Add Kconfig options to select different fb_ops helpers
  fbdev: Add initializer macros for struct fb_ops
  drm/armada: Use regular fbdev I/O helpers
  drm/exynos: Use regular fbdev I/O helpers
  drm/gma500: Use regular fbdev I/O helpers
  drm/radeon: Use regular fbdev I/O helpers
  drm/fbdev-dma: Use regular fbdev I/O helpers
  drm/omapdrm: Use regular fbdev I/O helpers
  drm/tegra: Use regular fbdev I/O helpers
  drm/fb-helper: Export helpers for marking damage areas
  drm/msm: Use regular fbdev I/O helpers
  drm/fbdev-generic: Implement dedicated fbdev I/O helpers
  drm/i915: Implement dedicated fbdev I/O helpers

 drivers/gpu/drm/Kconfig|  10 +-
 drivers/gpu/drm/armada/Kconfig |   1 +
 drivers/gpu/drm/armada/armada_fbdev.c  |   7 +-
 drivers/gpu/drm/drm_fb_helper.c| 236 ++---
 drivers/gpu/drm/drm_fbdev_dma.c|  11 +-
 drivers/gpu/drm/drm_fbdev_generic.c|  11 +-
 drivers/gpu/drm/exynos/Kconfig |   1 +
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |   9 +-
 drivers/gpu/drm/gma500/Kconfig |   1 +
 drivers/gpu/drm/gma500/fbdev.c |   8 +-
 drivers/gpu/drm/i915/Kconfig   |   1 +
 drivers/gpu/drm/i915/display/intel_fbdev.c |  14 +-
 drivers/gpu/drm/msm/Kconfig|   1 +
 drivers/gpu/drm/msm/msm_fbdev.c|  17 +-
 drivers/gpu/drm/omapdrm/Kconfig|   1 +
 drivers/gpu/drm/omapdrm/omap_fbdev.c   |  11 +-
 drivers/gpu/drm/radeon/Kconfig |   1 +
 drivers/gpu/drm/radeon/radeon_fbdev.c  |   9 +-
 drivers/gpu/drm/tegra/Kconfig  |   1 +
 drivers/gpu/drm/tegra/fbdev.c  |   8 +-
 drivers/video/fbdev/Kconfig|  21 ++
 include/drm/drm_fb_helper.h|  83 +---
 include/linux/fb.h | 112 ++
 23 files changed, 212 insertions(+), 363 deletions(-)


base-commit: cf59b48ea3c0c0075d7c4e8538177d38999da7b0
-- 
2.40.1



[Freedreno] [PATCH v5 01/13] fbdev: Add Kconfig options to select different fb_ops helpers

2023-05-30 Thread Thomas Zimmermann
Many fbdev drivers use the same set of fb_ops helpers. Add Kconfig
options to select them at once. This will help with making DRM's
fbdev emulation code more modular, but can also be used to simplify
fbdev's driver configs.

v3:
* fix select statement (Jingfeng)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Sui Jingfeng 
Reviewed-by: Sam Ravnborg 
---
 drivers/video/fbdev/Kconfig | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index e8889035c882..6df9bd09454a 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -158,6 +158,27 @@ config FB_DEFERRED_IO
bool
depends on FB
 
+config FB_IO_HELPERS
+   bool
+   depends on FB
+   select FB_CFB_COPYAREA
+   select FB_CFB_FILLRECT
+   select FB_CFB_IMAGEBLIT
+
+config FB_SYS_HELPERS
+   bool
+   depends on FB
+   select FB_SYS_COPYAREA
+   select FB_SYS_FILLRECT
+   select FB_SYS_FOPS
+   select FB_SYS_IMAGEBLIT
+
+config FB_SYS_HELPERS_DEFERRED
+   bool
+   depends on FB
+   select FB_DEFERRED_IO
+   select FB_SYS_HELPERS
+
 config FB_HECUBA
tristate
depends on FB
-- 
2.40.1



[Freedreno] [PATCH v5 04/13] drm/exynos: Use regular fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Exynos does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v3:
* don't reorder Makefile rules (Sam)
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Sam Ravnborg 
Cc: Inki Dae 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Krzysztof Kozlowski 
Cc: Alim Akhtar 
---
 drivers/gpu/drm/exynos/Kconfig| 1 +
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 9 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 0cb92d651ff1..7ca7e1dab52c 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -7,6 +7,7 @@ config DRM_EXYNOS
select DRM_DISPLAY_HELPER if DRM_EXYNOS_DP
select DRM_KMS_HELPER
select VIDEOMODE_HELPERS
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select SND_SOC_HDMI_CODEC if SND_SOC
help
  Choose this option if you have a Samsung SoC Exynos chipset.
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index ea4b3d248aac..fdf65587f1fe 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -8,6 +8,8 @@
  * Seung-Woo Kim 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -47,13 +49,10 @@ static void exynos_drm_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops exynos_drm_fb_ops = {
.owner  = THIS_MODULE,
+   __FB_DEFAULT_IO_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
+   __FB_DEFAULT_IO_OPS_DRAW,
.fb_mmap= exynos_drm_fb_mmap,
-   .fb_read= drm_fb_helper_cfb_read,
-   .fb_write   = drm_fb_helper_cfb_write,
-   .fb_fillrect= drm_fb_helper_cfb_fillrect,
-   .fb_copyarea= drm_fb_helper_cfb_copyarea,
-   .fb_imageblit   = drm_fb_helper_cfb_imageblit,
.fb_destroy = exynos_drm_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v5 02/13] fbdev: Add initializer macros for struct fb_ops

2023-05-30 Thread Thomas Zimmermann
For framebuffers in I/O and system memory, add macros that set
struct fb_ops to the respective callback functions.

For deferred I/O, add macros that generate callback functions with
damage handling. Add initializer macros that set struct fb_ops to
the generated callbacks.

These macros can remove a lot boilerplate code from fbdev drivers.
The drivers are supposed to use the macro that is required for its
framebuffer. Each macro is split into smaller helpers, so that
drivers with non-standard callbacks can pick and customize callbacks
as needed. There are individual helper macros for read/write, mmap
and drawing.

v5:
* fix whitespace errors (Jingfeng)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Sam Ravnborg 
---
 include/linux/fb.h | 112 +
 1 file changed, 112 insertions(+)

diff --git a/include/linux/fb.h b/include/linux/fb.h
index 2cf8efcb9e32..ce6823e157e6 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -538,9 +538,31 @@ extern ssize_t fb_io_read(struct fb_info *info, char 
__user *buf,
 extern ssize_t fb_io_write(struct fb_info *info, const char __user *buf,
   size_t count, loff_t *ppos);
 
+/*
+ * Initializes struct fb_ops for framebuffers in I/O memory.
+ */
+
+#define __FB_DEFAULT_IO_OPS_RDWR \
+   .fb_read= fb_io_read, \
+   .fb_write   = fb_io_write
+
+#define __FB_DEFAULT_IO_OPS_DRAW \
+   .fb_fillrect= cfb_fillrect, \
+   .fb_copyarea= cfb_copyarea, \
+   .fb_imageblit   = cfb_imageblit
+
+#define __FB_DEFAULT_IO_OPS_MMAP \
+   .fb_mmap= NULL // default implementation
+
+#define FB_DEFAULT_IO_OPS \
+   __FB_DEFAULT_IO_OPS_RDWR, \
+   __FB_DEFAULT_IO_OPS_DRAW, \
+   __FB_DEFAULT_IO_OPS_MMAP
+
 /*
  * Drawing operations where framebuffer is in system RAM
  */
+
 extern void sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
 extern void sys_copyarea(struct fb_info *info, const struct fb_copyarea *area);
 extern void sys_imageblit(struct fb_info *info, const struct fb_image *image);
@@ -549,6 +571,27 @@ extern ssize_t fb_sys_read(struct fb_info *info, char 
__user *buf,
 extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
 
+/*
+ * Initializes struct fb_ops for framebuffers in system memory.
+ */
+
+#define __FB_DEFAULT_SYS_OPS_RDWR \
+   .fb_read= fb_sys_read, \
+   .fb_write   = fb_sys_write
+
+#define __FB_DEFAULT_SYS_OPS_DRAW \
+   .fb_fillrect= sys_fillrect, \
+   .fb_copyarea= sys_copyarea, \
+   .fb_imageblit   = sys_imageblit
+
+#define __FB_DEFAULT_SYS_OPS_MMAP \
+   .fb_mmap= NULL // default implementation
+
+#define FB_DEFAULT_SYS_OPS \
+   __FB_DEFAULT_SYS_OPS_RDWR, \
+   __FB_DEFAULT_SYS_OPS_DRAW, \
+   __FB_DEFAULT_SYS_OPS_MMAP
+
 /* drivers/video/fbmem.c */
 extern int register_framebuffer(struct fb_info *fb_info);
 extern void unregister_framebuffer(struct fb_info *fb_info);
@@ -604,6 +647,75 @@ extern void fb_deferred_io_cleanup(struct fb_info *info);
 extern int fb_deferred_io_fsync(struct file *file, loff_t start,
loff_t end, int datasync);
 
+/*
+ * Generate callbacks for deferred I/O
+ */
+
+#define __FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, __mode) \
+   static ssize_t __prefix ## _defio_read(struct fb_info *info, char 
__user *buf, \
+  size_t count, loff_t *ppos) \
+   { \
+   return fb_ ## __mode ## _read(info, buf, count, ppos); \
+   } \
+   static ssize_t __prefix ## _defio_write(struct fb_info *info, const 
char __user *buf, \
+   size_t count, loff_t *ppos) \
+   { \
+   unsigned long offset = *ppos; \
+   ssize_t ret = fb_ ## __mode ## _write(info, buf, count, ppos); \
+   if (ret > 0) \
+   __damage_range(info, offset, ret); \
+   return ret; \
+   }
+
+#define __FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, __mode) \
+   static void __prefix ## _defio_fillrect(struct fb_info *info, \
+   const struct fb_fillrect *rect) 
\
+   { \
+   __mode ## _fillrect(info, rect); \
+   __damage_area(info, rect->dx, rect->dy, rect->width, 
rect->height); \
+   } \
+   static void __prefix ## _defio_copyarea(struct fb_info *info, \
+   const struct fb_copyarea *area) 
\
+   { \
+   __mode ## _copyarea(info, area); \
+   __damage_area(info, area->dx, area->dy, area->width, 
area->height); \
+   } \
+   static void __prefix ## _defio_imageblit(struct fb_info *info, \
+c

Re: [Freedreno] [PATCH v4 13/13] drm/i915: Implement dedicated fbdev I/O helpers

2023-05-30 Thread Thomas Zimmermann

Hi

Am 29.05.23 um 21:36 schrieb Sam Ravnborg:

Hi Thomas,

On Wed, May 24, 2023 at 11:21:50AM +0200, Thomas Zimmermann wrote:

Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Use an fbdev generator macro for
deferred I/O to create the fbdev callbacks. i915 was the only
caller of the DRM helpers, so remove them from the helper module.

i915's fbdev emulation is still incomplete as it doesn't implement
deferred I/O and damage handling for mmaped pages.

v4:
* generate deferred-I/O helpers
* use initializer macros for fb_ops
v2:
* use FB_IO_HELPERS options

Signed-off-by: Thomas Zimmermann 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: "Ville Syrjälä" 
---
  drivers/gpu/drm/Kconfig|   3 -
  drivers/gpu/drm/drm_fb_helper.c| 107 -
  drivers/gpu/drm/i915/Kconfig   |   1 +
  drivers/gpu/drm/i915/display/intel_fbdev.c |  14 +--
  include/drm/drm_fb_helper.h|  39 
  5 files changed, 9 insertions(+), 155 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 92a782827b7b..bb2e48cc6cd6 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -133,9 +133,6 @@ config DRM_FBDEV_EMULATION
bool "Enable legacy fbdev support for your modesetting driver"
depends on DRM_KMS_HELPER
depends on FB=y || FB=DRM_KMS_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index bab6b252f02a..9978147bbc8a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -736,113 +736,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, 
struct list_head *pagerefli
  }
  EXPORT_SYMBOL(drm_fb_helper_deferred_io);
  
-/**

- * drm_fb_helper_cfb_read - Implements struct &fb_ops.fb_read for I/O memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_io_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_read);
-
-/**
- * drm_fb_helper_cfb_write - Implements struct &fb_ops.fb_write for I/O memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_io_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
-drm_rect_width(&damage_area),
-drm_rect_height(&damage_area));
-   }


The generated helpers do not have the if (helper->funcs->fb_dirty)
check.
Is this implemented somewhere else that I missed?


It's not needed any longer.  We used to test if the fbdev code needs 
damage handling by looking for a fb_dirty callback. If so, we ran the 
damage handling code.


With the patchset applied, the fbdev code that does not need damage 
handling calls fb_{io,sys}_write() directly.  The fbdev code that needs 
damage handling (generic, i915, msm) uses the generator macro that 
creates necessary the calls unconditionally.  We know each case at build 
time.


(I think I have to move the msm patch after patch 10/13 to make it 
bisectable.)


AFAICT the missing test for fb_dirty is also one of the reasons why 
there's a difference in performance.


Hopefully, this answers your question?

Best regards
Thomas



Sam



-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_write);
-
-/**
- * drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around cfb_fillrect implemented by fbdev core
- */
-void drm

Re: [Freedreno] [v4, 12/13] drm/fbdev-generic: Implement dedicated fbdev I/O helpers

2023-05-26 Thread Thomas Zimmermann

Hi

Am 24.05.23 um 22:23 schrieb Sui Jingfeng:

Tested-by: Sui Jingfeng 


This version works fine, I have tested it On LoongArch with 
drm/loongson(v14) as it is most handy for me.


Also because it using fbdev-generic. fbdev of IGT report no error. Then 
I run fbtest from geert[1],



Before apply your patch:


Benchmarking... 10x10 squares: 468.39 Mpixels/s
Benchmarking... 20x20 squares: 985.02 Mpixels/s
Benchmarking... 50x50 squares: 2247.22 Mpixels/s
Benchmarking... 100x100 squares: 2242.30 Mpixels/s
Benchmarking... 200x200 squares: 2883.18 Mpixels/s
Benchmarking... 500x500 squares: 3642.18 Mpixels/s
Benchmarking... 1000x1000 squares: 3992.77 Mpixels/s
Benchmarking... R5 circles: 261.90 Mpixels/s
Benchmarking... R10 circles: 596.27 Mpixels/s
Benchmarking... R25 circles: 1513.96 Mpixels/s
Benchmarking... R50 circles: 1965.07 Mpixels/s
Benchmarking... R100 circles: 2470.75 Mpixels/s
Benchmarking... R250 circles: 3288.00 Mpixels/s
Benchmarking... R500 circles: 3705.66 Mpixels/s


After apply your patch:


Benchmarking... 10x10 squares: 477.04 Mpixels/s
Benchmarking... 20x20 squares: 1021.07 Mpixels/s
Benchmarking... 50x50 squares: 2315.70 Mpixels/s
Benchmarking... 100x100 squares: 2267.69 Mpixels/s
Benchmarking... 200x200 squares: 3006.28 Mpixels/s
Benchmarking... 500x500 squares: 3761.44 Mpixels/s
Benchmarking... 1000x1000 squares: 4112.49 Mpixels/s
Benchmarking... R5 circles: 269.19 Mpixels/s
Benchmarking... R10 circles: 620.77 Mpixels/s
Benchmarking... R25 circles: 1559.02 Mpixels/s
Benchmarking... R50 circles: 2027.36 Mpixels/s
Benchmarking... R100 circles: 2574.42 Mpixels/s
Benchmarking... R250 circles: 3363.28 Mpixels/s
Benchmarking... R500 circles: 3815.51 Mpixels/s


It seems that this bring a little bit performance gain.


Thanks for testing. I can't really tell why the code is now faster. All 
the patch really does is to eliminate an intermediate cross-module 
function call and the pointer derefs.  This, apparently, already has an 
impact.


Best regards
Thomas



Directly operate on video RAM is slower than have a shadow in system RAM.

I also test this patch in intel i3-8100 @ 3.6Ghz, the results show that 
i915 is a bit slower.


Because it operate directly on device memory.


[1] https://git.kernel.org/pub/scm/linux/kernel/git/geert/fbtest.git


On 2023/5/24 17:21, Thomas Zimmermann wrote:

Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Use an fbdev generator macro for
deferred I/O to create the callbacks. Fbdev-generic was the
only caller of the DRM helpers, so remove them from the helper
module.

v4:
* generate deferred-I/O helpers
* use initializer macros for fb_ops
v2:
* use FB_SYS_HELPERS_DEFERRED option

Signed-off-by: Thomas Zimmermann 
---
  drivers/gpu/drm/Kconfig |   6 +-
  drivers/gpu/drm/drm_fb_helper.c | 107 
  drivers/gpu/drm/drm_fbdev_generic.c |  11 ++-
  include/drm/drm_fb_helper.h |  41 ---
  4 files changed, 6 insertions(+), 159 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 77fb10ddd8a2..92a782827b7b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -95,6 +95,7 @@ config DRM_KUNIT_TEST
  config DRM_KMS_HELPER
  tristate
  depends on DRM
+    select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
  help
    CRTC helpers for KMS drivers.
@@ -135,11 +136,6 @@ config DRM_FBDEV_EMULATION
  select FB_CFB_FILLRECT
  select FB_CFB_COPYAREA
  select FB_CFB_IMAGEBLIT
-    select FB_DEFERRED_IO
-    select FB_SYS_FOPS
-    select FB_SYS_FILLRECT
-    select FB_SYS_COPYAREA
-    select FB_SYS_IMAGEBLIT
  select FRAMEBUFFER_CONSOLE if !EXPERT
  select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
  default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c 
b/drivers/gpu/drm/drm_fb_helper.c

index cb03099fd2e3..bab6b252f02a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -736,113 +736,6 @@ void drm_fb_helper_deferred_io(struct fb_info 
*info, struct list_head *pagerefli

  }
  EXPORT_SYMBOL(drm_fb_helper_deferred_io);
-/**
- * drm_fb_helper_sys_read - Implements struct &fb_ops.fb_read for 
system memory

- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-   size_t count, loff_t *ppos)
-{
-    return fb_sys_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_read);
-
-/**
- * drm_fb_helper_sys_write - Implements struct &fb_ops.fb_write for 
system memory

- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to wr

Re: [Freedreno] [v4, 02/13] fbdev: Add initializer macros for struct fb_ops

2023-05-26 Thread Thomas Zimmermann

Hi

Am 24.05.23 um 22:57 schrieb Sui Jingfeng:

Hi,


we love your patch:


On 2023/5/24 17:21, Thomas Zimmermann wrote:

For framebuffers in I/O and system memory, add macros that set
struct fb_ops to the respective callback functions.

For deferred I/O, add macros that generate callback functions with
damage handling. Add initializer macros that set struct fb_ops to
the generated callbacks.

These macros can remove a lot boilerplate code from fbdev drivers.
The drivers are supposed to use the macro that is required for its
framebuffer. Each macro is split into smaller helpers, so that
drivers with non-standard callbacks can pick and customize callbacks
as needed. There are individual helper macros for read/write, mmap
and drawing.

Signed-off-by: Thomas Zimmermann 
---
  include/linux/fb.h | 112 +
  1 file changed, 112 insertions(+)

diff --git a/include/linux/fb.h b/include/linux/fb.h
index 2cf8efcb9e32..731472a2bb62 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -538,9 +538,31 @@ extern ssize_t fb_io_read(struct fb_info *info, 
char __user *buf,
  extern ssize_t fb_io_write(struct fb_info *info, const char __user 
*buf,

 size_t count, loff_t *ppos);
+/*
+ * Initializes struct fb_ops for framebuffers in I/O memory.
+ */
+
+#define __FB_DEFAULT_IO_OPS_RDWR \
+    .fb_read    = fb_io_read, \
+    .fb_write    = fb_io_write
+
+#define __FB_DEFAULT_IO_OPS_DRAW \
+    .fb_fillrect    = cfb_fillrect, \
+    .fb_copyarea    = cfb_copyarea, \
+    .fb_imageblit    = cfb_imageblit


Here,  it seems that your text editor replace the tap with space, but 
I'm OK.


I'm asking because I see other __FB__DEFAULT_* macro begin with tabs.


Yeah, these are mistakes. I'll fix that with the next version.

Best regards
Thomas




+#define __FB_DEFAULT_IO_OPS_MMAP \
+    .fb_mmap    = NULL // default implementation
+
+#define FB_DEFAULT_IO_OPS \
+    __FB_DEFAULT_IO_OPS_RDWR, \
+    __FB_DEFAULT_IO_OPS_DRAW, \
+    __FB_DEFAULT_IO_OPS_MMAP
+
  /*
   * Drawing operations where framebuffer is in system RAM
   */
+
  extern void sys_fillrect(struct fb_info *info, const struct 
fb_fillrect *rect);
  extern void sys_copyarea(struct fb_info *info, const struct 
fb_copyarea *area);
  extern void sys_imageblit(struct fb_info *info, const struct 
fb_image *image);
@@ -549,6 +571,27 @@ extern ssize_t fb_sys_read(struct fb_info *info, 
char __user *buf,
  extern ssize_t fb_sys_write(struct fb_info *info, const char __user 
*buf,

  size_t count, loff_t *ppos);
+/*
+ * Initializes struct fb_ops for framebuffers in system memory.
+ */
+
+#define __FB_DEFAULT_SYS_OPS_RDWR \
+    .fb_read    = fb_sys_read, \
+    .fb_write    = fb_sys_write
+
+#define __FB_DEFAULT_SYS_OPS_DRAW \
+    .fb_fillrect    = sys_fillrect, \
+    .fb_copyarea    = sys_copyarea, \
+    .fb_imageblit    = sys_imageblit
+
+#define __FB_DEFAULT_SYS_OPS_MMAP \
+    .fb_mmap    = NULL // default implementation
+
+#define FB_DEFAULT_SYS_OPS \
+    __FB_DEFAULT_SYS_OPS_RDWR, \
+    __FB_DEFAULT_SYS_OPS_DRAW, \
+    __FB_DEFAULT_SYS_OPS_MMAP
+
  /* drivers/video/fbmem.c */
  extern int register_framebuffer(struct fb_info *fb_info);
  extern void unregister_framebuffer(struct fb_info *fb_info);
@@ -604,6 +647,75 @@ extern void fb_deferred_io_cleanup(struct fb_info 
*info);

  extern int fb_deferred_io_fsync(struct file *file, loff_t start,
  loff_t end, int datasync);
+/*
+ * Generate callbacks for deferred I/O
+ */
+
+#define __FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, 
__mode) \
+    static ssize_t __prefix ## _defio_read(struct fb_info *info, char 
__user *buf, \

+   size_t count, loff_t *ppos) \
+    { \
+    return fb_ ## __mode ## _read(info, buf, count, ppos); \
+    } \
+    static ssize_t __prefix ## _defio_write(struct fb_info *info, 
const char __user *buf, \

+    size_t count, loff_t *ppos) \
+    { \
+    unsigned long offset = *ppos; \
+    ssize_t ret = fb_ ## __mode ## _write(info, buf, count, ppos); \
+    if (ret > 0) \
+    __damage_range(info, offset, ret); \
+    return ret; \
+    }
+
+#define __FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, 
__mode) \

+    static void __prefix ## _defio_fillrect(struct fb_info *info, \
+    const struct fb_fillrect *rect) \
+    { \
+    __mode ## _fillrect(info, rect); \
+    __damage_area(info, rect->dx, rect->dy, rect->width, 
rect->height); \

+    } \
+    static void __prefix ## _defio_copyarea(struct fb_info *info, \
+    const struct fb_copyarea *area) \
+    { \
+    __mode ## _copyarea(info, area); \
+    __damage_area(info, area->dx, area->dy, area->width, 
area->height); \

+    } \
+    static void __prefix ## _defio_imageblit(struct fb_info *info, \
+   

[Freedreno] [PATCH v4 11/13] drm/fb-helper: Export helpers for marking damage areas

2023-05-24 Thread Thomas Zimmermann
Export drm_fb_helper_damage() and drm_fb_helper_damage_range(), which
handle damage areas for fbdev emulation. This is a temporary export
that allows to move the DRM I/O helpers for fbdev into drivers. Only
fbdev-generic and i915 need them. Both will be updated to implement
damage handling by themselves and the exported functions will be removed.

v4:
* update interfaces

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_fb_helper.c | 22 ++
 include/drm/drm_fb_helper.h |  3 +++
 2 files changed, 25 insertions(+)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index f0e9549b6bd7..cb03099fd2e3 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -670,6 +670,28 @@ static void drm_fb_helper_memory_range_to_clip(struct 
fb_info *info, off_t off,
drm_rect_init(clip, x1, y1, x2 - x1, y2 - y1);
 }
 
+/* Don't use in new code. */
+void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+   struct drm_rect damage_area;
+
+   drm_fb_helper_memory_range_to_clip(info, off, len, &damage_area);
+   drm_fb_helper_damage(fb_helper, damage_area.x1, damage_area.y1,
+drm_rect_width(&damage_area),
+drm_rect_height(&damage_area));
+}
+EXPORT_SYMBOL(drm_fb_helper_damage_range);
+
+/* Don't use in new code. */
+void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, 
u32 height)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+
+   drm_fb_helper_damage(fb_helper, x, y, width, height);
+}
+EXPORT_SYMBOL(drm_fb_helper_damage_area);
+
 /**
  * drm_fb_helper_deferred_io() - fbdev deferred_io callback function
  * @info: fb_info struct pointer
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 72032c354a30..7d5804882be7 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -253,6 +253,9 @@ void drm_fb_helper_fill_info(struct fb_info *info,
 struct drm_fb_helper *fb_helper,
 struct drm_fb_helper_surface_size *sizes);
 
+void drm_fb_helper_damage_range(struct fb_info *info, off_t off, size_t len);
+void drm_fb_helper_damage_area(struct fb_info *info, u32 x, u32 y, u32 width, 
u32 height);
+
 void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head 
*pagereflist);
 
 ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-- 
2.40.1



[Freedreno] [PATCH v4 07/13] drm/fbdev-dma: Use regular fbdev I/O helpers

2023-05-24 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Fbdev-dma does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/Kconfig |  1 +
 drivers/gpu/drm/drm_fbdev_dma.c | 11 +--
 2 files changed, 6 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index ba3fb04bb691..77fb10ddd8a2 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -223,6 +223,7 @@ config DRM_TTM_HELPER
 config DRM_GEM_DMA_HELPER
tristate
depends on DRM
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
help
  Choose this if you need the GEM DMA helper functions
 
diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c
index 728deffcc0d9..d86773fa8ab0 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: MIT
 
+#include 
+
 #include 
 #include 
 #include 
@@ -64,14 +66,11 @@ static const struct fb_ops drm_fbdev_dma_fb_ops = {
.owner = THIS_MODULE,
.fb_open = drm_fbdev_dma_fb_open,
.fb_release = drm_fbdev_dma_fb_release,
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
+   __FB_DEFAULT_SYS_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
-   .fb_destroy = drm_fbdev_dma_fb_destroy,
+   __FB_DEFAULT_SYS_OPS_DRAW,
.fb_mmap = drm_fbdev_dma_fb_mmap,
+   .fb_destroy = drm_fbdev_dma_fb_destroy,
 };
 
 /*
-- 
2.40.1



[Freedreno] [PATCH v4 09/13] drm/omapdrm: Use regular fbdev I/O helpers

2023-05-24 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Omapdrm does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Cc: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/Kconfig  |  1 +
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 11 +++
 2 files changed, 4 insertions(+), 8 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index 76ded1568bd0..b4ac76c9f31b 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -4,6 +4,7 @@ config DRM_OMAP
depends on DRM && OF
depends on ARCH_OMAP2PLUS
select DRM_KMS_HELPER
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select VIDEOMODE_HELPERS
select HDMI
default n
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index b950e93b3846..b7ccce0704a3 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -4,6 +4,8 @@
  * Author: Rob Clark 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -95,20 +97,13 @@ static void omap_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops omap_fb_ops = {
.owner = THIS_MODULE,
-
+   FB_DEFAULT_SYS_OPS,
.fb_check_var   = drm_fb_helper_check_var,
.fb_set_par = drm_fb_helper_set_par,
.fb_setcmap = drm_fb_helper_setcmap,
.fb_blank   = drm_fb_helper_blank,
.fb_pan_display = omap_fbdev_pan_display,
.fb_ioctl   = drm_fb_helper_ioctl,
-
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
-
.fb_destroy = omap_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v4 10/13] drm/tegra: Use regular fbdev I/O helpers

2023-05-24 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Tegra does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Cc: Thierry Reding 
Cc: Mikko Perttunen 
Cc: Jonathan Hunter 
---
 drivers/gpu/drm/tegra/Kconfig | 1 +
 drivers/gpu/drm/tegra/fbdev.c | 8 +++-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index 56453ca277c2..498313778175 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -12,6 +12,7 @@ config DRM_TEGRA
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select TEGRA_HOST1X
select INTERCONNECT
select IOMMU_IOVA
diff --git a/drivers/gpu/drm/tegra/fbdev.c b/drivers/gpu/drm/tegra/fbdev.c
index dca9eccae466..e74d9be981c7 100644
--- a/drivers/gpu/drm/tegra/fbdev.c
+++ b/drivers/gpu/drm/tegra/fbdev.c
@@ -8,6 +8,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include 
@@ -58,12 +59,9 @@ static void tegra_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops tegra_fb_ops = {
.owner = THIS_MODULE,
+   __FB_DEFAULT_SYS_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
+   __FB_DEFAULT_SYS_OPS_DRAW,
.fb_mmap = tegra_fb_mmap,
.fb_destroy = tegra_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v4 12/13] drm/fbdev-generic: Implement dedicated fbdev I/O helpers

2023-05-24 Thread Thomas Zimmermann
Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Use an fbdev generator macro for
deferred I/O to create the callbacks. Fbdev-generic was the
only caller of the DRM helpers, so remove them from the helper
module.

v4:
* generate deferred-I/O helpers
* use initializer macros for fb_ops
v2:
* use FB_SYS_HELPERS_DEFERRED option

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/Kconfig |   6 +-
 drivers/gpu/drm/drm_fb_helper.c | 107 
 drivers/gpu/drm/drm_fbdev_generic.c |  11 ++-
 include/drm/drm_fb_helper.h |  41 ---
 4 files changed, 6 insertions(+), 159 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 77fb10ddd8a2..92a782827b7b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -95,6 +95,7 @@ config DRM_KUNIT_TEST
 config DRM_KMS_HELPER
tristate
depends on DRM
+   select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
help
  CRTC helpers for KMS drivers.
 
@@ -135,11 +136,6 @@ config DRM_FBDEV_EMULATION
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
-   select FB_DEFERRED_IO
-   select FB_SYS_FOPS
-   select FB_SYS_FILLRECT
-   select FB_SYS_COPYAREA
-   select FB_SYS_IMAGEBLIT
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index cb03099fd2e3..bab6b252f02a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -736,113 +736,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, 
struct list_head *pagerefli
 }
 EXPORT_SYMBOL(drm_fb_helper_deferred_io);
 
-/**
- * drm_fb_helper_sys_read - Implements struct &fb_ops.fb_read for system memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_sys_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_read);
-
-/**
- * drm_fb_helper_sys_write - Implements struct &fb_ops.fb_write for system 
memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_sys_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
-drm_rect_width(&damage_area),
-drm_rect_height(&damage_area));
-   }
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_write);
-
-/**
- * drm_fb_helper_sys_fillrect - wrapper around sys_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around sys_fillrect implemented by fbdev core
- */
-void drm_fb_helper_sys_fillrect(struct fb_info *info,
-   const struct fb_fillrect *rect)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_fillrect(info, rect);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, 
rect->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_fillrect);
-
-/**
- * drm_fb_helper_sys_copyarea - wrapper around sys_copyarea
- * @info: fbdev registered by the helper
- * @area: info about area to copy
- *
- * A wrapper around sys_copyarea implemented by fbdev core
- */
-void drm_fb_helper_sys_copyarea(struct fb_info *info,
-   const struct fb_copyarea *area)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_copyarea(info, area);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, area->dx, area->dy, area->width, 
area->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_copyarea);
-
-/**
- * drm_fb_helper_sys_imageblit - wrapper around sys_i

[Freedreno] [PATCH v4 08/13] drm/msm: Use regular fbdev I/O helpers

2023-05-24 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Msm does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

Msm's fbdev emulation has been incomplete as it didn't implement
damage handling. Partilly fix this by implementing damage handling
for write and draw operation. It is still missing for mmaped pages.

v4:
* use initializer macros for struct fb_ops
* partially support damage handling
v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Dmitry Baryshkov 
Cc: Rob Clark 
Cc: Abhinav Kumar 
Cc: Dmitry Baryshkov 
Cc: Sean Paul 
---
 drivers/gpu/drm/msm/Kconfig |  1 +
 drivers/gpu/drm/msm/msm_fbdev.c | 17 -
 2 files changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 85f5ab1d552c..a78662bd6273 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -21,6 +21,7 @@ config DRM_MSM
select DRM_BRIDGE
select DRM_PANEL_BRIDGE
select DRM_SCHED
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select SHMEM
select TMPFS
select QCOM_SCM
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index ce0ba6d1979a..fa9c1cbffae3 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -4,6 +4,8 @@
  * Author: Rob Clark 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -23,6 +25,10 @@ module_param(fbdev, bool, 0600);
  * fbdev funcs, to implement legacy fbdev interface on top of drm driver
  */
 
+FB_GEN_DEFAULT_DEFERRED_SYS_OPS(msm_fbdev,
+   drm_fb_helper_damage_range,
+   drm_fb_helper_damage_area)
+
 static int msm_fbdev_mmap(struct fb_info *info, struct vm_area_struct *vma)
 {
struct drm_fb_helper *helper = (struct drm_fb_helper *)info->par;
@@ -52,16 +58,9 @@ static void msm_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops msm_fb_ops = {
.owner = THIS_MODULE,
+   __FB_DEFAULT_DEFERRED_OPS_RDWR(msm_fbdev),
DRM_FB_HELPER_DEFAULT_OPS,
-
-   /* Note: to properly handle manual update displays, we wrap the
-* basic fbdev ops which write to the framebuffer
-*/
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
+   __FB_DEFAULT_DEFERRED_OPS_DRAW(msm_fbdev),
.fb_mmap = msm_fbdev_mmap,
.fb_destroy = msm_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v4 00/13] drm/fbdev: Remove DRM's helpers for fbdev I/O

2023-05-24 Thread Thomas Zimmermann
DRM provides a number of wrappers around fbdev cfb_() sys_(), fb_io_()
and fb_sys_() helpers. The DRM functions don't provide any additional
functionality for most DRM drivers. So remove them and call the fbdev
I/O helpers directly.

The DRM fbdev I/O wrappers were originally added because 
does not protect its content with CONFIG_FB. DRM fbdev emulation did
not build if the config option had been disabled. This has been
fixed. For fbdev-generic and i915, the wrappers added support for damage
handling. But this is better handled within the two callers, as each
is special in its damage handling.

Patch 1 adds several internal Kconfig options that DRM drivers (and
possibly other fbdev code) will use to select the correct set of I/O
helpers. Patch 2 adds initializers for struct fb_ops and generator
macros for the callback functions. These macros will simplify drivers.
This patchset applies the new options and macros to DRM fbdev emulation,
but regular fbdev drivers can use them as well.

Patches 3 to 10 replace the DRM wrappers in a number of fbdev emulations.
Patch 10 exports two helpers for damage handling. Patches 12 and 13
update fbdev-generic and i915 with the help of the exported functions.
The patches also remove DRM's fbdev I/O helpers, which are now unused.

DRM's fbdev helpers had to select fbdev I/O helpers for I/O and for
system memory. Each fbdev emulation now selects the correct helpers
for itself. Depending on the selected DRM drivers, kernel builds will
now only contain the necessary fbdev I/O helpers and might be slightly
smaller in size.

v4:
* use initializer and generator macros for struct fb_ops
* partially support damage handling in msm (Dmitri)
v3:
* fix Kconfig options (Jingfeng)
* minimize changes to exynos (Sam)
v2:
* simplify Kconfig handling (Sam)

Thomas Zimmermann (13):
  fbdev: Add Kconfig options to select different fb_ops helpers
  fbdev: Add initializer macros for struct fb_ops
  drm/armada: Use regular fbdev I/O helpers
  drm/exynos: Use regular fbdev I/O helpers
  drm/gma500: Use regular fbdev I/O helpers
  drm/radeon: Use regular fbdev I/O helpers
  drm/fbdev-dma: Use regular fbdev I/O helpers
  drm/msm: Use regular fbdev I/O helpers
  drm/omapdrm: Use regular fbdev I/O helpers
  drm/tegra: Use regular fbdev I/O helpers
  drm/fb-helper: Export helpers for marking damage areas
  drm/fbdev-generic: Implement dedicated fbdev I/O helpers
  drm/i915: Implement dedicated fbdev I/O helpers

 drivers/gpu/drm/Kconfig|  10 +-
 drivers/gpu/drm/armada/Kconfig |   1 +
 drivers/gpu/drm/armada/armada_fbdev.c  |   7 +-
 drivers/gpu/drm/drm_fb_helper.c| 236 ++---
 drivers/gpu/drm/drm_fbdev_dma.c|  11 +-
 drivers/gpu/drm/drm_fbdev_generic.c|  11 +-
 drivers/gpu/drm/exynos/Kconfig |   1 +
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |   9 +-
 drivers/gpu/drm/gma500/Kconfig |   1 +
 drivers/gpu/drm/gma500/fbdev.c |   8 +-
 drivers/gpu/drm/i915/Kconfig   |   1 +
 drivers/gpu/drm/i915/display/intel_fbdev.c |  14 +-
 drivers/gpu/drm/msm/Kconfig|   1 +
 drivers/gpu/drm/msm/msm_fbdev.c|  17 +-
 drivers/gpu/drm/omapdrm/Kconfig|   1 +
 drivers/gpu/drm/omapdrm/omap_fbdev.c   |  11 +-
 drivers/gpu/drm/radeon/Kconfig |   1 +
 drivers/gpu/drm/radeon/radeon_fbdev.c  |   9 +-
 drivers/gpu/drm/tegra/Kconfig  |   1 +
 drivers/gpu/drm/tegra/fbdev.c  |   8 +-
 drivers/video/fbdev/Kconfig|  21 ++
 include/drm/drm_fb_helper.h|  83 +---
 include/linux/fb.h | 112 ++
 23 files changed, 212 insertions(+), 363 deletions(-)


base-commit: 216281f91018b24567e59ae46ce7e96fb92063cf
prerequisite-patch-id: 0aa359f6144c4015c140c8a6750be19099c676fb
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
prerequisite-patch-id: cbc453ee02fae02af22fbfdce56ab732c7a88c36
prerequisite-patch-id: 8bff2b12862e44027a25837ea7510f633d40839e
prerequisite-patch-id: 97ac107455aff4e0ec039d166ecdd2430d20f22e
-- 
2.40.1



[Freedreno] [PATCH v4 13/13] drm/i915: Implement dedicated fbdev I/O helpers

2023-05-24 Thread Thomas Zimmermann
Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Use an fbdev generator macro for
deferred I/O to create the fbdev callbacks. i915 was the only
caller of the DRM helpers, so remove them from the helper module.

i915's fbdev emulation is still incomplete as it doesn't implement
deferred I/O and damage handling for mmaped pages.

v4:
* generate deferred-I/O helpers
* use initializer macros for fb_ops
v2:
* use FB_IO_HELPERS options

Signed-off-by: Thomas Zimmermann 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: "Ville Syrjälä" 
---
 drivers/gpu/drm/Kconfig|   3 -
 drivers/gpu/drm/drm_fb_helper.c| 107 -
 drivers/gpu/drm/i915/Kconfig   |   1 +
 drivers/gpu/drm/i915/display/intel_fbdev.c |  14 +--
 include/drm/drm_fb_helper.h|  39 
 5 files changed, 9 insertions(+), 155 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 92a782827b7b..bb2e48cc6cd6 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -133,9 +133,6 @@ config DRM_FBDEV_EMULATION
bool "Enable legacy fbdev support for your modesetting driver"
depends on DRM_KMS_HELPER
depends on FB=y || FB=DRM_KMS_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index bab6b252f02a..9978147bbc8a 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -736,113 +736,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, 
struct list_head *pagerefli
 }
 EXPORT_SYMBOL(drm_fb_helper_deferred_io);
 
-/**
- * drm_fb_helper_cfb_read - Implements struct &fb_ops.fb_read for I/O memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_io_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_read);
-
-/**
- * drm_fb_helper_cfb_write - Implements struct &fb_ops.fb_write for I/O memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_io_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
-drm_rect_width(&damage_area),
-drm_rect_height(&damage_area));
-   }
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_write);
-
-/**
- * drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around cfb_fillrect implemented by fbdev core
- */
-void drm_fb_helper_cfb_fillrect(struct fb_info *info,
-   const struct fb_fillrect *rect)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   cfb_fillrect(info, rect);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, 
rect->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect);
-
-/**
- * drm_fb_helper_cfb_copyarea - wrapper around cfb_copyarea
- * @info: fbdev registered by the helper
- * @area: info about area to copy
- *
- * A wrapper around cfb_copyarea implemented by fbdev core
- */
-void drm_fb_helper_cfb_copyarea(struct fb_info *info,
-   const struct fb_copyarea *area)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   cfb_copyarea(info, area);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, area->dx, area->dy, area->width, 
area->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb

[Freedreno] [PATCH v4 03/13] drm/armada: Use regular fbdev I/O helpers

2023-05-24 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Armada does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Cc: Russell King 
---
 drivers/gpu/drm/armada/Kconfig| 1 +
 drivers/gpu/drm/armada/armada_fbdev.c | 7 ++-
 2 files changed, 3 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig
index f5c66d89ba99..5afade25e217 100644
--- a/drivers/gpu/drm/armada/Kconfig
+++ b/drivers/gpu/drm/armada/Kconfig
@@ -3,6 +3,7 @@ config DRM_ARMADA
tristate "DRM support for Marvell Armada SoCs"
depends on DRM && HAVE_CLK && ARM && MMU
select DRM_KMS_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
help
  Support the "LCD" controllers found on the Marvell Armada 510
  devices.  There are two controllers on the device, each controller
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c 
b/drivers/gpu/drm/armada/armada_fbdev.c
index 0a5fd1aa86eb..3943e89cc06c 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
@@ -33,12 +34,8 @@ static void armada_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops armada_fb_ops = {
.owner  = THIS_MODULE,
+   FB_DEFAULT_IO_OPS,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_read= drm_fb_helper_cfb_read,
-   .fb_write   = drm_fb_helper_cfb_write,
-   .fb_fillrect= drm_fb_helper_cfb_fillrect,
-   .fb_copyarea= drm_fb_helper_cfb_copyarea,
-   .fb_imageblit   = drm_fb_helper_cfb_imageblit,
.fb_destroy = armada_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v4 06/13] drm/radeon: Use regular fbdev I/O helpers

2023-05-24 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Radeon does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Alex Deucher 
Cc: Alex Deucher 
Cc: "Christian König" 
Cc: "Pan, Xinhui" 
---
 drivers/gpu/drm/radeon/Kconfig| 1 +
 drivers/gpu/drm/radeon/radeon_fbdev.c | 9 +++--
 2 files changed, 4 insertions(+), 6 deletions(-)

diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig
index e19d77d58810..fe498c8af1bb 100644
--- a/drivers/gpu/drm/radeon/Kconfig
+++ b/drivers/gpu/drm/radeon/Kconfig
@@ -11,6 +11,7 @@ config DRM_RADEON
select DRM_SUBALLOC_HELPER
 select DRM_TTM
select DRM_TTM_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select SND_HDA_COMPONENT if SND_HDA_CORE
select POWER_SUPPLY
select HWMON
diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c 
b/drivers/gpu/drm/radeon/radeon_fbdev.c
index fe76e29910ef..28212c2d6c98 100644
--- a/drivers/gpu/drm/radeon/radeon_fbdev.c
+++ b/drivers/gpu/drm/radeon/radeon_fbdev.c
@@ -24,6 +24,7 @@
  * David Airlie
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -190,14 +191,10 @@ static void radeon_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops radeon_fbdev_fb_ops = {
.owner = THIS_MODULE,
-   DRM_FB_HELPER_DEFAULT_OPS,
.fb_open = radeon_fbdev_fb_open,
.fb_release = radeon_fbdev_fb_release,
-   .fb_read = drm_fb_helper_cfb_read,
-   .fb_write = drm_fb_helper_cfb_write,
-   .fb_fillrect = drm_fb_helper_cfb_fillrect,
-   .fb_copyarea = drm_fb_helper_cfb_copyarea,
-   .fb_imageblit = drm_fb_helper_cfb_imageblit,
+   FB_DEFAULT_IO_OPS,
+   DRM_FB_HELPER_DEFAULT_OPS,
.fb_destroy = radeon_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v4 02/13] fbdev: Add initializer macros for struct fb_ops

2023-05-24 Thread Thomas Zimmermann
For framebuffers in I/O and system memory, add macros that set
struct fb_ops to the respective callback functions.

For deferred I/O, add macros that generate callback functions with
damage handling. Add initializer macros that set struct fb_ops to
the generated callbacks.

These macros can remove a lot boilerplate code from fbdev drivers.
The drivers are supposed to use the macro that is required for its
framebuffer. Each macro is split into smaller helpers, so that
drivers with non-standard callbacks can pick and customize callbacks
as needed. There are individual helper macros for read/write, mmap
and drawing.

Signed-off-by: Thomas Zimmermann 
---
 include/linux/fb.h | 112 +
 1 file changed, 112 insertions(+)

diff --git a/include/linux/fb.h b/include/linux/fb.h
index 2cf8efcb9e32..731472a2bb62 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -538,9 +538,31 @@ extern ssize_t fb_io_read(struct fb_info *info, char 
__user *buf,
 extern ssize_t fb_io_write(struct fb_info *info, const char __user *buf,
   size_t count, loff_t *ppos);
 
+/*
+ * Initializes struct fb_ops for framebuffers in I/O memory.
+ */
+
+#define __FB_DEFAULT_IO_OPS_RDWR \
+   .fb_read= fb_io_read, \
+   .fb_write   = fb_io_write
+
+#define __FB_DEFAULT_IO_OPS_DRAW \
+.fb_fillrect   = cfb_fillrect, \
+.fb_copyarea   = cfb_copyarea, \
+.fb_imageblit  = cfb_imageblit
+
+#define __FB_DEFAULT_IO_OPS_MMAP \
+   .fb_mmap= NULL // default implementation
+
+#define FB_DEFAULT_IO_OPS \
+   __FB_DEFAULT_IO_OPS_RDWR, \
+   __FB_DEFAULT_IO_OPS_DRAW, \
+   __FB_DEFAULT_IO_OPS_MMAP
+
 /*
  * Drawing operations where framebuffer is in system RAM
  */
+
 extern void sys_fillrect(struct fb_info *info, const struct fb_fillrect *rect);
 extern void sys_copyarea(struct fb_info *info, const struct fb_copyarea *area);
 extern void sys_imageblit(struct fb_info *info, const struct fb_image *image);
@@ -549,6 +571,27 @@ extern ssize_t fb_sys_read(struct fb_info *info, char 
__user *buf,
 extern ssize_t fb_sys_write(struct fb_info *info, const char __user *buf,
size_t count, loff_t *ppos);
 
+/*
+ * Initializes struct fb_ops for framebuffers in system memory.
+ */
+
+#define __FB_DEFAULT_SYS_OPS_RDWR \
+   .fb_read= fb_sys_read, \
+   .fb_write   = fb_sys_write
+
+#define __FB_DEFAULT_SYS_OPS_DRAW \
+.fb_fillrect   = sys_fillrect, \
+.fb_copyarea   = sys_copyarea, \
+.fb_imageblit  = sys_imageblit
+
+#define __FB_DEFAULT_SYS_OPS_MMAP \
+   .fb_mmap= NULL // default implementation
+
+#define FB_DEFAULT_SYS_OPS \
+   __FB_DEFAULT_SYS_OPS_RDWR, \
+   __FB_DEFAULT_SYS_OPS_DRAW, \
+   __FB_DEFAULT_SYS_OPS_MMAP
+
 /* drivers/video/fbmem.c */
 extern int register_framebuffer(struct fb_info *fb_info);
 extern void unregister_framebuffer(struct fb_info *fb_info);
@@ -604,6 +647,75 @@ extern void fb_deferred_io_cleanup(struct fb_info *info);
 extern int fb_deferred_io_fsync(struct file *file, loff_t start,
loff_t end, int datasync);
 
+/*
+ * Generate callbacks for deferred I/O
+ */
+
+#define __FB_GEN_DEFAULT_DEFERRED_OPS_RDWR(__prefix, __damage_range, __mode) \
+   static ssize_t __prefix ## _defio_read(struct fb_info *info, char 
__user *buf, \
+  size_t count, loff_t *ppos) \
+   { \
+   return fb_ ## __mode ## _read(info, buf, count, ppos); \
+   } \
+   static ssize_t __prefix ## _defio_write(struct fb_info *info, const 
char __user *buf, \
+   size_t count, loff_t *ppos) \
+   { \
+   unsigned long offset = *ppos; \
+   ssize_t ret = fb_ ## __mode ## _write(info, buf, count, ppos); \
+   if (ret > 0) \
+   __damage_range(info, offset, ret); \
+   return ret; \
+   }
+
+#define __FB_GEN_DEFAULT_DEFERRED_OPS_DRAW(__prefix, __damage_area, __mode) \
+   static void __prefix ## _defio_fillrect(struct fb_info *info, \
+   const struct fb_fillrect *rect) 
\
+   { \
+   __mode ## _fillrect(info, rect); \
+   __damage_area(info, rect->dx, rect->dy, rect->width, 
rect->height); \
+   } \
+   static void __prefix ## _defio_copyarea(struct fb_info *info, \
+   const struct fb_copyarea *area) 
\
+   { \
+   __mode ## _copyarea(info, area); \
+   __damage_area(info, area->dx, area->dy, area->width, 
area->height); \
+   } \
+   static void __prefix ## _defio_imageblit(struct fb_info *info, \
+const struct fb_image *image) \
+   { \
+   __mod

[Freedreno] [PATCH v4 04/13] drm/exynos: Use regular fbdev I/O helpers

2023-05-24 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Exynos does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v3:
* don't reorder Makefile rules (Sam)
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Cc: Inki Dae 
Cc: Seung-Woo Kim 
Cc: Kyungmin Park 
Cc: Krzysztof Kozlowski 
Cc: Alim Akhtar 
---
 drivers/gpu/drm/exynos/Kconfig| 1 +
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 9 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/exynos/Kconfig b/drivers/gpu/drm/exynos/Kconfig
index 0cb92d651ff1..7ca7e1dab52c 100644
--- a/drivers/gpu/drm/exynos/Kconfig
+++ b/drivers/gpu/drm/exynos/Kconfig
@@ -7,6 +7,7 @@ config DRM_EXYNOS
select DRM_DISPLAY_HELPER if DRM_EXYNOS_DP
select DRM_KMS_HELPER
select VIDEOMODE_HELPERS
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select SND_SOC_HDMI_CODEC if SND_SOC
help
  Choose this option if you have a Samsung SoC Exynos chipset.
diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index ea4b3d248aac..fdf65587f1fe 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -8,6 +8,8 @@
  * Seung-Woo Kim 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -47,13 +49,10 @@ static void exynos_drm_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops exynos_drm_fb_ops = {
.owner  = THIS_MODULE,
+   __FB_DEFAULT_IO_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
+   __FB_DEFAULT_IO_OPS_DRAW,
.fb_mmap= exynos_drm_fb_mmap,
-   .fb_read= drm_fb_helper_cfb_read,
-   .fb_write   = drm_fb_helper_cfb_write,
-   .fb_fillrect= drm_fb_helper_cfb_fillrect,
-   .fb_copyarea= drm_fb_helper_cfb_copyarea,
-   .fb_imageblit   = drm_fb_helper_cfb_imageblit,
.fb_destroy = exynos_drm_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v4 05/13] drm/gma500: Use regular fbdev I/O helpers

2023-05-24 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Gma500 does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v4:
* use initializer macros for struct fb_ops
v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Cc: Patrik Jakobsson 
---
 drivers/gpu/drm/gma500/Kconfig | 1 +
 drivers/gpu/drm/gma500/fbdev.c | 8 +++-
 2 files changed, 4 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig
index 2efc0eb41c64..cd3d92725ed4 100644
--- a/drivers/gpu/drm/gma500/Kconfig
+++ b/drivers/gpu/drm/gma500/Kconfig
@@ -3,6 +3,7 @@ config DRM_GMA500
tristate "Intel GMA500/600/3600/3650 KMS Framebuffer"
depends on DRM && PCI && X86 && MMU
select DRM_KMS_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select I2C
select I2C_ALGOBIT
# GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915
diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c
index 4f0309548b2b..955cbe9f05a7 100644
--- a/drivers/gpu/drm/gma500/fbdev.c
+++ b/drivers/gpu/drm/gma500/fbdev.c
@@ -5,6 +5,7 @@
  *
  **/
 
+#include 
 #include 
 
 #include 
@@ -134,13 +135,10 @@ static void psb_fbdev_fb_destroy(struct fb_info *info)
 
 static const struct fb_ops psb_fbdev_fb_ops = {
.owner = THIS_MODULE,
+   __FB_DEFAULT_IO_OPS_RDWR,
DRM_FB_HELPER_DEFAULT_OPS,
.fb_setcolreg = psb_fbdev_fb_setcolreg,
-   .fb_read = drm_fb_helper_cfb_read,
-   .fb_write = drm_fb_helper_cfb_write,
-   .fb_fillrect = drm_fb_helper_cfb_fillrect,
-   .fb_copyarea = drm_fb_helper_cfb_copyarea,
-   .fb_imageblit = drm_fb_helper_cfb_imageblit,
+   __FB_DEFAULT_IO_OPS_DRAW,
.fb_mmap = psb_fbdev_fb_mmap,
.fb_destroy = psb_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v4 01/13] fbdev: Add Kconfig options to select different fb_ops helpers

2023-05-24 Thread Thomas Zimmermann
Many fbdev drivers use the same set of fb_ops helpers. Add Kconfig
options to select them at once. This will help with making DRM's
fbdev emulation code more modular, but can also be used to simplify
fbdev's driver configs.

v3:
* fix select statement (Jingfeng)

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/Kconfig | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index e8889035c882..6df9bd09454a 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -158,6 +158,27 @@ config FB_DEFERRED_IO
bool
depends on FB
 
+config FB_IO_HELPERS
+   bool
+   depends on FB
+   select FB_CFB_COPYAREA
+   select FB_CFB_FILLRECT
+   select FB_CFB_IMAGEBLIT
+
+config FB_SYS_HELPERS
+   bool
+   depends on FB
+   select FB_SYS_COPYAREA
+   select FB_SYS_FILLRECT
+   select FB_SYS_FOPS
+   select FB_SYS_IMAGEBLIT
+
+config FB_SYS_HELPERS_DEFERRED
+   bool
+   depends on FB
+   select FB_DEFERRED_IO
+   select FB_SYS_HELPERS
+
 config FB_HECUBA
tristate
depends on FB
-- 
2.40.1



Re: [Freedreno] [PATCH v3 11/12] drm/fbdev-generic: Implement dedicated fbdev I/O helpers

2023-05-23 Thread Thomas Zimmermann



Am 22.05.23 um 20:46 schrieb Thomas Zimmermann:
[...]


Looking at this patch makes me wonder if we should have implemented
fb_dirty for the MSM driver. We have drm_framebuffer_funcs::dirty()
implemented (by wrapping the drm_atomic_helper_dirtyfb()).


I think so. You'd need something similar to the generic fbdev emulation. 
But it's for a separate patchset. Apparently no one has complained so far.


I have another revision of these patches in the works and will add 
initial support for damage handling.




Best regards
Thomas





diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 77fb10ddd8a2..92a782827b7b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -95,6 +95,7 @@ config DRM_KUNIT_TEST
  config DRM_KMS_HELPER
 tristate
 depends on DRM
+   select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
 help
   CRTC helpers for KMS drivers.

@@ -135,11 +136,6 @@ config DRM_FBDEV_EMULATION
 select FB_CFB_FILLRECT
 select FB_CFB_COPYAREA
 select FB_CFB_IMAGEBLIT
-   select FB_DEFERRED_IO
-   select FB_SYS_FOPS
-   select FB_SYS_FILLRECT
-   select FB_SYS_COPYAREA
-   select FB_SYS_IMAGEBLIT
 select FRAMEBUFFER_CONSOLE if !EXPERT
 select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if 
FRAMEBUFFER_CONSOLE

 default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c 
b/drivers/gpu/drm/drm_fb_helper.c

index 8724e08c518b..ba0a808f14ee 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -729,113 +729,6 @@ void drm_fb_helper_deferred_io(struct fb_info 
*info, struct list_head *pagerefli

  }
  EXPORT_SYMBOL(drm_fb_helper_deferred_io);

-/**
- * drm_fb_helper_sys_read - Implements struct &fb_ops.fb_read for 
system memory

- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_sys_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_read);
-
-/**
- * drm_fb_helper_sys_write - Implements struct &fb_ops.fb_write for 
system memory

- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char 
__user *buf,

-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_sys_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, 
damage_area.y1,

-    drm_rect_width(&damage_area),
-    drm_rect_height(&damage_area));
-   }
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_write);
-
-/**
- * drm_fb_helper_sys_fillrect - wrapper around sys_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around sys_fillrect implemented by fbdev core
- */
-void drm_fb_helper_sys_fillrect(struct fb_info *info,
-   const struct fb_fillrect *rect)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_fillrect(info, rect);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, rect->dx, rect->dy, 
rect->width, rect->height);

-}
-EXPORT_SYMBOL(drm_fb_helper_sys_fillrect);
-
-/**
- * drm_fb_helper_sys_copyarea - wrapper around sys_copyarea
- * @info: fbdev registered by the helper
- * @area: info about area to copy
- *
- * A wrapper around sys_copyarea implemented by fbdev core
- */
-void drm_fb_helper_sys_copyarea(struct fb_info *info,
-   const struct fb_copyarea *area)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_copyarea(info, area);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, area->dx, area->dy, 
area->width, area->height);

-}
-EXPORT_SYMBOL(drm_fb_helper_sys_copyarea);
-
-/**
- * drm_fb_helper_sys_imageblit - wrapper around sys_imageblit
- * @info: fbdev registered by the helper
- * @image: info about image to blit
- *
- * A wrapper around sys_imageblit i

[Freedreno] [PATCH] drm/msm: Use struct fb_info.screen_buffer

2023-05-22 Thread Thomas Zimmermann
The fbdev framebuffer is in system memory. Store the address in
the field 'screen_buffer'. Fixes the following sparse warning.

../drivers/gpu/drm/msm/msm_fbdev.c:124:26: warning: incorrect type in 
assignment (different address spaces)
../drivers/gpu/drm/msm/msm_fbdev.c:124:26:expected char [noderef] __iomem 
*screen_base
../drivers/gpu/drm/msm/msm_fbdev.c:124:26:got void *

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/msm/msm_fbdev.c | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index 2ebc86381e1c..ce0ba6d1979a 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -121,9 +121,9 @@ static int msm_fbdev_create(struct drm_fb_helper *helper,
 
drm_fb_helper_fill_info(fbi, helper, sizes);
 
-   fbi->screen_base = msm_gem_get_vaddr(bo);
-   if (IS_ERR(fbi->screen_base)) {
-   ret = PTR_ERR(fbi->screen_base);
+   fbi->screen_buffer = msm_gem_get_vaddr(bo);
+   if (IS_ERR(fbi->screen_buffer)) {
+   ret = PTR_ERR(fbi->screen_buffer);
goto fail;
}
fbi->screen_size = bo->size;
-- 
2.40.1



Re: [Freedreno] [PATCH v3 11/12] drm/fbdev-generic: Implement dedicated fbdev I/O helpers

2023-05-22 Thread Thomas Zimmermann

Hi

Am 22.05.23 um 15:20 schrieb Dmitry Baryshkov:

On Mon, 22 May 2023 at 15:22, Thomas Zimmermann  wrote:


Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Fbdev-generic was the only caller of the
DRM helpers, so remove them from the helper module.

v2:
 * use FB_SYS_HELPERS_DEFERRED option

Signed-off-by: Thomas Zimmermann 
---
  drivers/gpu/drm/Kconfig |   6 +-
  drivers/gpu/drm/drm_fb_helper.c | 107 
  drivers/gpu/drm/drm_fbdev_generic.c |  47 ++--
  include/drm/drm_fb_helper.h |  41 ---
  4 files changed, 43 insertions(+), 158 deletions(-)


Looking at this patch makes me wonder if we should have implemented
fb_dirty for the MSM driver. We have drm_framebuffer_funcs::dirty()
implemented (by wrapping the drm_atomic_helper_dirtyfb()).


I think so. You'd need something similar to the generic fbdev emulation. 
But it's for a separate patchset. Apparently no one has complained so far.


Best regards
Thomas





diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 77fb10ddd8a2..92a782827b7b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -95,6 +95,7 @@ config DRM_KUNIT_TEST
  config DRM_KMS_HELPER
 tristate
 depends on DRM
+   select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
 help
   CRTC helpers for KMS drivers.

@@ -135,11 +136,6 @@ config DRM_FBDEV_EMULATION
 select FB_CFB_FILLRECT
 select FB_CFB_COPYAREA
 select FB_CFB_IMAGEBLIT
-   select FB_DEFERRED_IO
-   select FB_SYS_FOPS
-   select FB_SYS_FILLRECT
-   select FB_SYS_COPYAREA
-   select FB_SYS_IMAGEBLIT
 select FRAMEBUFFER_CONSOLE if !EXPERT
 select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
 default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 8724e08c518b..ba0a808f14ee 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -729,113 +729,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, 
struct list_head *pagerefli
  }
  EXPORT_SYMBOL(drm_fb_helper_deferred_io);

-/**
- * drm_fb_helper_sys_read - Implements struct &fb_ops.fb_read for system memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_sys_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_read);
-
-/**
- * drm_fb_helper_sys_write - Implements struct &fb_ops.fb_write for system 
memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_sys_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
-drm_rect_width(&damage_area),
-drm_rect_height(&damage_area));
-   }
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_write);
-
-/**
- * drm_fb_helper_sys_fillrect - wrapper around sys_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around sys_fillrect implemented by fbdev core
- */
-void drm_fb_helper_sys_fillrect(struct fb_info *info,
-   const struct fb_fillrect *rect)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_fillrect(info, rect);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, 
rect->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_fillrect);
-
-/**
- * drm_fb_helper_sys_copyarea - wrapper around sys_copyarea
- * @info: fbdev registered by the helper
- * @area: info about area to copy
- *
- * A wrapper around sys_copyarea implemented by fbdev core
- */
-void drm_fb_helper_sys_copyarea(struct fb_info *info,
-   const struct fb

[Freedreno] [PATCH v3 11/12] drm/fbdev-generic: Implement dedicated fbdev I/O helpers

2023-05-22 Thread Thomas Zimmermann
Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. Fbdev-generic was the only caller of the
DRM helpers, so remove them from the helper module.

v2:
* use FB_SYS_HELPERS_DEFERRED option

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/Kconfig |   6 +-
 drivers/gpu/drm/drm_fb_helper.c | 107 
 drivers/gpu/drm/drm_fbdev_generic.c |  47 ++--
 include/drm/drm_fb_helper.h |  41 ---
 4 files changed, 43 insertions(+), 158 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 77fb10ddd8a2..92a782827b7b 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -95,6 +95,7 @@ config DRM_KUNIT_TEST
 config DRM_KMS_HELPER
tristate
depends on DRM
+   select FB_SYS_HELPERS_DEFERRED if DRM_FBDEV_EMULATION
help
  CRTC helpers for KMS drivers.
 
@@ -135,11 +136,6 @@ config DRM_FBDEV_EMULATION
select FB_CFB_FILLRECT
select FB_CFB_COPYAREA
select FB_CFB_IMAGEBLIT
-   select FB_DEFERRED_IO
-   select FB_SYS_FOPS
-   select FB_SYS_FILLRECT
-   select FB_SYS_COPYAREA
-   select FB_SYS_IMAGEBLIT
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index 8724e08c518b..ba0a808f14ee 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -729,113 +729,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, 
struct list_head *pagerefli
 }
 EXPORT_SYMBOL(drm_fb_helper_deferred_io);
 
-/**
- * drm_fb_helper_sys_read - Implements struct &fb_ops.fb_read for system memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_sys_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_read);
-
-/**
- * drm_fb_helper_sys_write - Implements struct &fb_ops.fb_write for system 
memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_sys_write(struct fb_info *info, const char __user *buf,
-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_sys_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
-drm_rect_width(&damage_area),
-drm_rect_height(&damage_area));
-   }
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_write);
-
-/**
- * drm_fb_helper_sys_fillrect - wrapper around sys_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around sys_fillrect implemented by fbdev core
- */
-void drm_fb_helper_sys_fillrect(struct fb_info *info,
-   const struct fb_fillrect *rect)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_fillrect(info, rect);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, 
rect->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_fillrect);
-
-/**
- * drm_fb_helper_sys_copyarea - wrapper around sys_copyarea
- * @info: fbdev registered by the helper
- * @area: info about area to copy
- *
- * A wrapper around sys_copyarea implemented by fbdev core
- */
-void drm_fb_helper_sys_copyarea(struct fb_info *info,
-   const struct fb_copyarea *area)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   sys_copyarea(info, area);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, area->dx, area->dy, area->width, 
area->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_sys_copyarea);
-
-/**
- * drm_fb_helper_sys_imageblit - wrapper around sys_imageblit
- * @info: fbdev registered by the helper
- * @image: info about image to blit
- *
- * A wrapper around sys_imageblit implem

[Freedreno] [PATCH v3 12/12] drm/i915: Implement dedicated fbdev I/O helpers

2023-05-22 Thread Thomas Zimmermann
Implement dedicated fbdev helpers for framebuffer I/O instead
of using DRM's helpers. i915 was the only caller of the DRM
helpers, so remove them from the helper module.

v2:
* use FB_IO_HELPERS options

Signed-off-by: Thomas Zimmermann 
Cc: Jani Nikula 
Cc: Joonas Lahtinen 
Cc: Rodrigo Vivi 
Cc: Tvrtko Ursulin 
Cc: "Ville Syrjälä" 
---
 drivers/gpu/drm/Kconfig|   3 -
 drivers/gpu/drm/drm_fb_helper.c| 107 -
 drivers/gpu/drm/i915/Kconfig   |   1 +
 drivers/gpu/drm/i915/display/intel_fbdev.c |  51 --
 include/drm/drm_fb_helper.h|  39 
 5 files changed, 46 insertions(+), 155 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index 92a782827b7b..bb2e48cc6cd6 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -133,9 +133,6 @@ config DRM_FBDEV_EMULATION
bool "Enable legacy fbdev support for your modesetting driver"
depends on DRM_KMS_HELPER
depends on FB=y || FB=DRM_KMS_HELPER
-   select FB_CFB_FILLRECT
-   select FB_CFB_COPYAREA
-   select FB_CFB_IMAGEBLIT
select FRAMEBUFFER_CONSOLE if !EXPERT
select FRAMEBUFFER_CONSOLE_DETECT_PRIMARY if FRAMEBUFFER_CONSOLE
default y
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index ba0a808f14ee..5927896ad8f6 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -729,113 +729,6 @@ void drm_fb_helper_deferred_io(struct fb_info *info, 
struct list_head *pagerefli
 }
 EXPORT_SYMBOL(drm_fb_helper_deferred_io);
 
-/**
- * drm_fb_helper_cfb_read - Implements struct &fb_ops.fb_read for I/O memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to read from framebuffer memory
- * @count: number of bytes to read from framebuffer memory
- * @ppos: read offset within framebuffer memory
- *
- * Returns:
- * The number of bytes read on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_cfb_read(struct fb_info *info, char __user *buf,
-  size_t count, loff_t *ppos)
-{
-   return fb_io_read(info, buf, count, ppos);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_read);
-
-/**
- * drm_fb_helper_cfb_write - Implements struct &fb_ops.fb_write for I/O memory
- * @info: fb_info struct pointer
- * @buf: userspace buffer to write to framebuffer memory
- * @count: number of bytes to write to framebuffer memory
- * @ppos: write offset within framebuffer memory
- *
- * Returns:
- * The number of bytes written on success, or an error code otherwise.
- */
-ssize_t drm_fb_helper_cfb_write(struct fb_info *info, const char __user *buf,
-   size_t count, loff_t *ppos)
-{
-   struct drm_fb_helper *helper = info->par;
-   loff_t pos = *ppos;
-   ssize_t ret;
-   struct drm_rect damage_area;
-
-   ret = fb_io_write(info, buf, count, ppos);
-   if (ret <= 0)
-   return ret;
-
-   if (helper->funcs->fb_dirty) {
-   drm_fb_helper_memory_range_to_clip(info, pos, ret, 
&damage_area);
-   drm_fb_helper_damage(helper, damage_area.x1, damage_area.y1,
-drm_rect_width(&damage_area),
-drm_rect_height(&damage_area));
-   }
-
-   return ret;
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_write);
-
-/**
- * drm_fb_helper_cfb_fillrect - wrapper around cfb_fillrect
- * @info: fbdev registered by the helper
- * @rect: info about rectangle to fill
- *
- * A wrapper around cfb_fillrect implemented by fbdev core
- */
-void drm_fb_helper_cfb_fillrect(struct fb_info *info,
-   const struct fb_fillrect *rect)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   cfb_fillrect(info, rect);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, rect->dx, rect->dy, rect->width, 
rect->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_fillrect);
-
-/**
- * drm_fb_helper_cfb_copyarea - wrapper around cfb_copyarea
- * @info: fbdev registered by the helper
- * @area: info about area to copy
- *
- * A wrapper around cfb_copyarea implemented by fbdev core
- */
-void drm_fb_helper_cfb_copyarea(struct fb_info *info,
-   const struct fb_copyarea *area)
-{
-   struct drm_fb_helper *helper = info->par;
-
-   cfb_copyarea(info, area);
-
-   if (helper->funcs->fb_dirty)
-   drm_fb_helper_damage(helper, area->dx, area->dy, area->width, 
area->height);
-}
-EXPORT_SYMBOL(drm_fb_helper_cfb_copyarea);
-
-/**
- * drm_fb_helper_cfb_imageblit - wrapper around cfb_imageblit
- * @info: fbdev registered by the helper
- * @image: info about image to blit
- *
- * A wrapper around cfb_imageblit implemented by fbdev core
- */
-void drm_fb_helper_cfb_imageblit(struct fb_info *i

[Freedreno] [PATCH v3 10/12] drm/fb-helper: Export helpers for marking damage areas

2023-05-22 Thread Thomas Zimmermann
Export drm_fb_helper_damage() and drm_fb_helper_damage_range(), which
handle damage areas for fbdev emulation. This is a temporary export
that allows to move the DRM I/O helpers for fbdev into drivers. Only
fbdev-generic and i915 need them. Both will be updated to implement
damage handling by themselves and the exported functions will be removed.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_fb_helper.c | 19 +--
 include/drm/drm_fb_helper.h |  4 
 2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index f0e9549b6bd7..8724e08c518b 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -625,13 +625,15 @@ static void drm_fb_helper_add_damage_clip(struct 
drm_fb_helper *helper, u32 x, u
spin_unlock_irqrestore(&helper->damage_lock, flags);
 }
 
-static void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y,
-u32 width, u32 height)
+/* Don't use in new code. */
+void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y,
+ u32 width, u32 height)
 {
drm_fb_helper_add_damage_clip(helper, x, y, width, height);
 
schedule_work(&helper->damage_work);
 }
+EXPORT_SYMBOL(drm_fb_helper_damage);
 
 /*
  * Convert memory region into area of scanlines and pixels per
@@ -670,6 +672,19 @@ static void drm_fb_helper_memory_range_to_clip(struct 
fb_info *info, off_t off,
drm_rect_init(clip, x1, y1, x2 - x1, y2 - y1);
 }
 
+/* Don't use in new code. */
+void drm_fb_helper_damage_range(struct drm_fb_helper *fb_helper, off_t off, 
size_t len)
+{
+   struct fb_info *info = fb_helper->info;
+   struct drm_rect damage_area;
+
+   drm_fb_helper_memory_range_to_clip(info, off, len, &damage_area);
+   drm_fb_helper_damage(fb_helper, damage_area.x1, damage_area.y1,
+drm_rect_width(&damage_area),
+drm_rect_height(&damage_area));
+}
+EXPORT_SYMBOL(drm_fb_helper_damage_range);
+
 /**
  * drm_fb_helper_deferred_io() - fbdev deferred_io callback function
  * @info: fb_info struct pointer
diff --git a/include/drm/drm_fb_helper.h b/include/drm/drm_fb_helper.h
index 72032c354a30..80c402f4e379 100644
--- a/include/drm/drm_fb_helper.h
+++ b/include/drm/drm_fb_helper.h
@@ -253,6 +253,10 @@ void drm_fb_helper_fill_info(struct fb_info *info,
 struct drm_fb_helper *fb_helper,
 struct drm_fb_helper_surface_size *sizes);
 
+void drm_fb_helper_damage(struct drm_fb_helper *helper, u32 x, u32 y,
+ u32 width, u32 height);
+void drm_fb_helper_damage_range(struct drm_fb_helper *helper, off_t off, 
size_t len);
+
 void drm_fb_helper_deferred_io(struct fb_info *info, struct list_head 
*pagereflist);
 
 ssize_t drm_fb_helper_sys_read(struct fb_info *info, char __user *buf,
-- 
2.40.1



[Freedreno] [PATCH v3 09/12] drm/tegra: Use regular fbdev I/O helpers

2023-05-22 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Tegra does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Cc: Thierry Reding 
Cc: Mikko Perttunen 
Cc: Jonathan Hunter 
---
 drivers/gpu/drm/tegra/Kconfig |  1 +
 drivers/gpu/drm/tegra/fbdev.c | 11 ++-
 2 files changed, 7 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/tegra/Kconfig b/drivers/gpu/drm/tegra/Kconfig
index 56453ca277c2..498313778175 100644
--- a/drivers/gpu/drm/tegra/Kconfig
+++ b/drivers/gpu/drm/tegra/Kconfig
@@ -12,6 +12,7 @@ config DRM_TEGRA
select DRM_KMS_HELPER
select DRM_MIPI_DSI
select DRM_PANEL
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select TEGRA_HOST1X
select INTERCONNECT
select IOMMU_IOVA
diff --git a/drivers/gpu/drm/tegra/fbdev.c b/drivers/gpu/drm/tegra/fbdev.c
index dca9eccae466..144d851e566f 100644
--- a/drivers/gpu/drm/tegra/fbdev.c
+++ b/drivers/gpu/drm/tegra/fbdev.c
@@ -8,6 +8,7 @@
  */
 
 #include 
+#include 
 #include 
 
 #include 
@@ -59,11 +60,11 @@ static void tegra_fbdev_fb_destroy(struct fb_info *info)
 static const struct fb_ops tegra_fb_ops = {
.owner = THIS_MODULE,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
+   .fb_read = fb_sys_read,
+   .fb_write = fb_sys_write,
+   .fb_fillrect = sys_fillrect,
+   .fb_copyarea = sys_copyarea,
+   .fb_imageblit = sys_imageblit,
.fb_mmap = tegra_fb_mmap,
.fb_destroy = tegra_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v3 02/12] drm/armada: Use regular fbdev I/O helpers

2023-05-22 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Armada does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Cc: Russell King 
---
 drivers/gpu/drm/armada/Kconfig| 1 +
 drivers/gpu/drm/armada/armada_fbdev.c | 9 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/armada/Kconfig b/drivers/gpu/drm/armada/Kconfig
index f5c66d89ba99..5afade25e217 100644
--- a/drivers/gpu/drm/armada/Kconfig
+++ b/drivers/gpu/drm/armada/Kconfig
@@ -3,6 +3,7 @@ config DRM_ARMADA
tristate "DRM support for Marvell Armada SoCs"
depends on DRM && HAVE_CLK && ARM && MMU
select DRM_KMS_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
help
  Support the "LCD" controllers found on the Marvell Armada 510
  devices.  There are two controllers on the device, each controller
diff --git a/drivers/gpu/drm/armada/armada_fbdev.c 
b/drivers/gpu/drm/armada/armada_fbdev.c
index 0a5fd1aa86eb..6c3bbaf53569 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -5,6 +5,7 @@
  */
 
 #include 
+#include 
 #include 
 #include 
 
@@ -34,11 +35,9 @@ static void armada_fbdev_fb_destroy(struct fb_info *info)
 static const struct fb_ops armada_fb_ops = {
.owner  = THIS_MODULE,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_read= drm_fb_helper_cfb_read,
-   .fb_write   = drm_fb_helper_cfb_write,
-   .fb_fillrect= drm_fb_helper_cfb_fillrect,
-   .fb_copyarea= drm_fb_helper_cfb_copyarea,
-   .fb_imageblit   = drm_fb_helper_cfb_imageblit,
+   .fb_fillrect= cfb_fillrect,
+   .fb_copyarea= cfb_copyarea,
+   .fb_imageblit   = cfb_imageblit,
.fb_destroy = armada_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v3 07/12] drm/msm: Use regular fbdev I/O helpers

2023-05-22 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Msm does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Dmitry Baryshkov 
Cc: Rob Clark 
Cc: Abhinav Kumar 
Cc: Dmitry Baryshkov 
Cc: Sean Paul 
---
 drivers/gpu/drm/msm/Kconfig |  1 +
 drivers/gpu/drm/msm/msm_fbdev.c | 12 +++-
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/msm/Kconfig b/drivers/gpu/drm/msm/Kconfig
index 85f5ab1d552c..a78662bd6273 100644
--- a/drivers/gpu/drm/msm/Kconfig
+++ b/drivers/gpu/drm/msm/Kconfig
@@ -21,6 +21,7 @@ config DRM_MSM
select DRM_BRIDGE
select DRM_PANEL_BRIDGE
select DRM_SCHED
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select SHMEM
select TMPFS
select QCOM_SCM
diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index 2ebc86381e1c..fc0353a4160e 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -4,6 +4,8 @@
  * Author: Rob Clark 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -57,11 +59,11 @@ static const struct fb_ops msm_fb_ops = {
/* Note: to properly handle manual update displays, we wrap the
 * basic fbdev ops which write to the framebuffer
 */
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
+   .fb_read = fb_sys_read,
+   .fb_write = fb_sys_write,
+   .fb_fillrect = sys_fillrect,
+   .fb_copyarea = sys_copyarea,
+   .fb_imageblit = sys_imageblit,
.fb_mmap = msm_fbdev_mmap,
.fb_destroy = msm_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v3 06/12] drm/fbdev-dma: Use regular fbdev I/O helpers

2023-05-22 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Fbdev-dma does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/Kconfig |  1 +
 drivers/gpu/drm/drm_fbdev_dma.c | 12 +++-
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/Kconfig b/drivers/gpu/drm/Kconfig
index ba3fb04bb691..77fb10ddd8a2 100644
--- a/drivers/gpu/drm/Kconfig
+++ b/drivers/gpu/drm/Kconfig
@@ -223,6 +223,7 @@ config DRM_TTM_HELPER
 config DRM_GEM_DMA_HELPER
tristate
depends on DRM
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
help
  Choose this if you need the GEM DMA helper functions
 
diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c
index 728deffcc0d9..09a36dc38c43 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -1,5 +1,7 @@
 // SPDX-License-Identifier: MIT
 
+#include 
+
 #include 
 #include 
 #include 
@@ -64,12 +66,12 @@ static const struct fb_ops drm_fbdev_dma_fb_ops = {
.owner = THIS_MODULE,
.fb_open = drm_fbdev_dma_fb_open,
.fb_release = drm_fbdev_dma_fb_release,
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
+   .fb_read = fb_sys_read,
+   .fb_write = fb_sys_write,
DRM_FB_HELPER_DEFAULT_OPS,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
+   .fb_fillrect = sys_fillrect,
+   .fb_copyarea = sys_copyarea,
+   .fb_imageblit = sys_imageblit,
.fb_destroy = drm_fbdev_dma_fb_destroy,
.fb_mmap = drm_fbdev_dma_fb_mmap,
 };
-- 
2.40.1



[Freedreno] [PATCH v3 05/12] drm/radeon: Use regular fbdev I/O helpers

2023-05-22 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Radeon does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Acked-by: Alex Deucher 
Cc: Alex Deucher 
Cc: "Christian König" 
Cc: "Pan, Xinhui" 
---
 drivers/gpu/drm/radeon/Kconfig| 1 +
 drivers/gpu/drm/radeon/radeon_fbdev.c | 9 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/radeon/Kconfig b/drivers/gpu/drm/radeon/Kconfig
index e19d77d58810..fe498c8af1bb 100644
--- a/drivers/gpu/drm/radeon/Kconfig
+++ b/drivers/gpu/drm/radeon/Kconfig
@@ -11,6 +11,7 @@ config DRM_RADEON
select DRM_SUBALLOC_HELPER
 select DRM_TTM
select DRM_TTM_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select SND_HDA_COMPONENT if SND_HDA_CORE
select POWER_SUPPLY
select HWMON
diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c 
b/drivers/gpu/drm/radeon/radeon_fbdev.c
index fe76e29910ef..dcabe527f9c0 100644
--- a/drivers/gpu/drm/radeon/radeon_fbdev.c
+++ b/drivers/gpu/drm/radeon/radeon_fbdev.c
@@ -24,6 +24,7 @@
  * David Airlie
  */
 
+#include 
 #include 
 #include 
 #include 
@@ -193,11 +194,9 @@ static const struct fb_ops radeon_fbdev_fb_ops = {
DRM_FB_HELPER_DEFAULT_OPS,
.fb_open = radeon_fbdev_fb_open,
.fb_release = radeon_fbdev_fb_release,
-   .fb_read = drm_fb_helper_cfb_read,
-   .fb_write = drm_fb_helper_cfb_write,
-   .fb_fillrect = drm_fb_helper_cfb_fillrect,
-   .fb_copyarea = drm_fb_helper_cfb_copyarea,
-   .fb_imageblit = drm_fb_helper_cfb_imageblit,
+   .fb_fillrect = cfb_fillrect,
+   .fb_copyarea = cfb_copyarea,
+   .fb_imageblit = cfb_imageblit,
.fb_destroy = radeon_fbdev_fb_destroy,
 };
 
-- 
2.40.1



[Freedreno] [PATCH v3 08/12] drm/omapdrm: Use regular fbdev I/O helpers

2023-05-22 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Omapdrm does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v2:
* use FB_SYS_HELPERS option

Signed-off-by: Thomas Zimmermann 
Cc: Tomi Valkeinen 
---
 drivers/gpu/drm/omapdrm/Kconfig  |  1 +
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 12 +++-
 2 files changed, 8 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/Kconfig b/drivers/gpu/drm/omapdrm/Kconfig
index 76ded1568bd0..b4ac76c9f31b 100644
--- a/drivers/gpu/drm/omapdrm/Kconfig
+++ b/drivers/gpu/drm/omapdrm/Kconfig
@@ -4,6 +4,7 @@ config DRM_OMAP
depends on DRM && OF
depends on ARCH_OMAP2PLUS
select DRM_KMS_HELPER
+   select FB_SYS_HELPERS if DRM_FBDEV_EMULATION
select VIDEOMODE_HELPERS
select HDMI
default n
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index b950e93b3846..55a65b81ccdc 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -4,6 +4,8 @@
  * Author: Rob Clark 
  */
 
+#include 
+
 #include 
 #include 
 #include 
@@ -103,11 +105,11 @@ static const struct fb_ops omap_fb_ops = {
.fb_pan_display = omap_fbdev_pan_display,
.fb_ioctl   = drm_fb_helper_ioctl,
 
-   .fb_read = drm_fb_helper_sys_read,
-   .fb_write = drm_fb_helper_sys_write,
-   .fb_fillrect = drm_fb_helper_sys_fillrect,
-   .fb_copyarea = drm_fb_helper_sys_copyarea,
-   .fb_imageblit = drm_fb_helper_sys_imageblit,
+   .fb_read = fb_sys_read,
+   .fb_write = fb_sys_write,
+   .fb_fillrect = sys_fillrect,
+   .fb_copyarea = sys_copyarea,
+   .fb_imageblit = sys_imageblit,
 
.fb_destroy = omap_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v3 04/12] drm/gma500: Use regular fbdev I/O helpers

2023-05-22 Thread Thomas Zimmermann
Use the regular fbdev helpers for framebuffer I/O instead of DRM's
helpers. Gma500 does not use damage handling, so DRM's fbdev helpers
are mere wrappers around the fbdev code.

By using fbdev helpers directly within each DRM fbdev emulation,
we can eventually remove DRM's wrapper functions entirely.

v2:
* use FB_IO_HELPERS option

Signed-off-by: Thomas Zimmermann 
Cc: Patrik Jakobsson 
---
 drivers/gpu/drm/gma500/Kconfig | 1 +
 drivers/gpu/drm/gma500/fbdev.c | 9 -
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/drivers/gpu/drm/gma500/Kconfig b/drivers/gpu/drm/gma500/Kconfig
index 2efc0eb41c64..cd3d92725ed4 100644
--- a/drivers/gpu/drm/gma500/Kconfig
+++ b/drivers/gpu/drm/gma500/Kconfig
@@ -3,6 +3,7 @@ config DRM_GMA500
tristate "Intel GMA500/600/3600/3650 KMS Framebuffer"
depends on DRM && PCI && X86 && MMU
select DRM_KMS_HELPER
+   select FB_IO_HELPERS if DRM_FBDEV_EMULATION
select I2C
select I2C_ALGOBIT
# GMA500 depends on ACPI_VIDEO when ACPI is enabled, just like i915
diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c
index 62287407e717..60005c3d01d0 100644
--- a/drivers/gpu/drm/gma500/fbdev.c
+++ b/drivers/gpu/drm/gma500/fbdev.c
@@ -5,6 +5,7 @@
  *
  **/
 
+#include 
 #include 
 
 #include 
@@ -136,11 +137,9 @@ static const struct fb_ops psb_fbdev_fb_ops = {
.owner = THIS_MODULE,
DRM_FB_HELPER_DEFAULT_OPS,
.fb_setcolreg = psb_fbdev_fb_setcolreg,
-   .fb_read = drm_fb_helper_cfb_read,
-   .fb_write = drm_fb_helper_cfb_write,
-   .fb_fillrect = drm_fb_helper_cfb_fillrect,
-   .fb_copyarea = drm_fb_helper_cfb_copyarea,
-   .fb_imageblit = drm_fb_helper_cfb_imageblit,
+   .fb_fillrect = cfb_fillrect,
+   .fb_copyarea = cfb_copyarea,
+   .fb_imageblit = cfb_imageblit,
.fb_mmap = psb_fbdev_fb_mmap,
.fb_destroy = psb_fbdev_fb_destroy,
 };
-- 
2.40.1



[Freedreno] [PATCH v3 01/12] fbdev: Add Kconfig options to select different fb_ops helpers

2023-05-22 Thread Thomas Zimmermann
Many fbdev drivers use the same set of fb_ops helpers. Add Kconfig
options to select them at once. This will help with making DRM's
fbdev emulation code more modular, but can also be used to simplify
fbdev's driver configs.

v3:
* fix select statement (Jingfeng)

Signed-off-by: Thomas Zimmermann 
---
 drivers/video/fbdev/Kconfig | 21 +
 1 file changed, 21 insertions(+)

diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
index 485e8c35d5c6..6e4b6ad9d8e6 100644
--- a/drivers/video/fbdev/Kconfig
+++ b/drivers/video/fbdev/Kconfig
@@ -158,6 +158,27 @@ config FB_DEFERRED_IO
bool
depends on FB
 
+config FB_IO_HELPERS
+   bool
+   depends on FB
+   select FB_CFB_COPYAREA
+   select FB_CFB_FILLRECT
+   select FB_CFB_IMAGEBLIT
+
+config FB_SYS_HELPERS
+   bool
+   depends on FB
+   select FB_SYS_COPYAREA
+   select FB_SYS_FILLRECT
+   select FB_SYS_FOPS
+   select FB_SYS_IMAGEBLIT
+
+config FB_SYS_HELPERS_DEFERRED
+   bool
+   depends on FB
+   select FB_DEFERRED_IO
+   select FB_SYS_HELPERS
+
 config FB_HECUBA
tristate
depends on FB
-- 
2.40.1



[Freedreno] [PATCH v3 00/12] drm/fbdev: Remove DRM's helpers for fbdev I/O

2023-05-22 Thread Thomas Zimmermann
DRM provides a number of wrappers around fbdev cfb_() sys_(), fb_io_()
and fb_sys_() helpers. The DRM functions don't provide any additional
functionality for most DRM drivers. So remove them and call the fbdev
I/O helpers directly.

The DRM fbdev I/O wrappers were originally added because 
does not protect its content with CONFIG_FB. DRM fbdev emulation did
not build if the config option had been disabled. This has been
fixed. For fbdev-generic and i915, the wrappers added support for damage
handling. But this is better handled within the two callers, as each
is special in its damage handling.

Patch 1 adds several internal Kconfig otpions that DRM drivers (and
possibly other fbdev code) will use to select the correct set of I/O
helpers.

Patches 2 to 9 replace the DRM wrappers in a number of fbdev emulations.
Patch 10 exports two helpers for damage handling. Patches 11 and 12
update fbdev-generic and i915 with the help of the exported functions.
The patches also remove DRM's fbdev I/O helpers, which are now unused.

DRM's fbdev helpers had to select fbdev I/O helpers for I/O and for
system memory. Each fbdev emulation now selects the correct helpers
for itself. Depending on the selected DRM drivers, kernel builds will
now only contain the necessary fbdev I/O helpers and might be slightly
smaller in size.

v3:
* fix Kconfig options (Jingfeng)
* minimize changes to exynos (Sam)
v2:
* simplify Kconfig handling (Sam)

Thomas Zimmermann (12):
  fbdev: Add Kconfig options to select different fb_ops helpers
  drm/armada: Use regular fbdev I/O helpers
  drm/exynos: Use regular fbdev I/O helpers
  drm/gma500: Use regular fbdev I/O helpers
  drm/radeon: Use regular fbdev I/O helpers
  drm/fbdev-dma: Use regular fbdev I/O helpers
  drm/msm: Use regular fbdev I/O helpers
  drm/omapdrm: Use regular fbdev I/O helpers
  drm/tegra: Use regular fbdev I/O helpers
  drm/fb-helper: Export helpers for marking damage areas
  drm/fbdev-generic: Implement dedicated fbdev I/O helpers
  drm/i915: Implement dedicated fbdev I/O helpers

 drivers/gpu/drm/Kconfig|  10 +-
 drivers/gpu/drm/armada/Kconfig |   1 +
 drivers/gpu/drm/armada/armada_fbdev.c  |   9 +-
 drivers/gpu/drm/drm_fb_helper.c| 233 ++---
 drivers/gpu/drm/drm_fbdev_dma.c|  12 +-
 drivers/gpu/drm/drm_fbdev_generic.c|  47 -
 drivers/gpu/drm/exynos/Kconfig |   1 +
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |  10 +-
 drivers/gpu/drm/gma500/Kconfig |   1 +
 drivers/gpu/drm/gma500/fbdev.c |   9 +-
 drivers/gpu/drm/i915/Kconfig   |   1 +
 drivers/gpu/drm/i915/display/intel_fbdev.c |  51 -
 drivers/gpu/drm/msm/Kconfig|   1 +
 drivers/gpu/drm/msm/msm_fbdev.c|  12 +-
 drivers/gpu/drm/omapdrm/Kconfig|   1 +
 drivers/gpu/drm/omapdrm/omap_fbdev.c   |  12 +-
 drivers/gpu/drm/radeon/Kconfig |   1 +
 drivers/gpu/drm/radeon/radeon_fbdev.c  |   9 +-
 drivers/gpu/drm/tegra/Kconfig  |   1 +
 drivers/gpu/drm/tegra/fbdev.c  |  11 +-
 drivers/video/fbdev/Kconfig|  21 ++
 include/drm/drm_fb_helper.h|  84 +---
 22 files changed, 183 insertions(+), 355 deletions(-)


base-commit: f533234d40e8f5b8599bd5bc97fa8e30384aec03
prerequisite-patch-id: 0aa359f6144c4015c140c8a6750be19099c676fb
prerequisite-patch-id: c67e5d886a47b7d0266d81100837557fda34cb24
prerequisite-patch-id: cbc453ee02fae02af22fbfdce56ab732c7a88c36
-- 
2.40.1



  1   2   3   4   5   6   >