[PATCH v2 1/3] drm/mgag200: Consolidate VGA output

2024-06-10 Thread Thomas Zimmermann
The various models have common code for the VGA output's encoder and
connector. Move everything into a single shared source file. Remove some
obsolete initializer macros. No functional changes.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/Makefile  |  3 +-
 drivers/gpu/drm/mgag200/mgag200_drv.h | 24 +++-
 drivers/gpu/drm/mgag200/mgag200_g200.c| 46 +--
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  | 46 +--
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 46 +--
 drivers/gpu/drm/mgag200/mgag200_g200er.c  | 46 +--
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  | 46 +--
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 46 +--
 drivers/gpu/drm/mgag200/mgag200_g200se.c  | 46 +--
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  | 46 +--
 drivers/gpu/drm/mgag200/mgag200_vga.c | 68 +++
 11 files changed, 95 insertions(+), 368 deletions(-)
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_vga.c

diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile
index 0b919352046eb..d1b25f9f6586e 100644
--- a/drivers/gpu/drm/mgag200/Makefile
+++ b/drivers/gpu/drm/mgag200/Makefile
@@ -11,6 +11,7 @@ mgag200-y := \
mgag200_g200ew3.o \
mgag200_g200se.o \
mgag200_g200wb.o \
-   mgag200_mode.o
+   mgag200_mode.o \
+   mgag200_vga.o
 
 obj-$(CONFIG_DRM_MGAG200) += mgag200.o
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h 
b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 20e3710e056b3..db89fddc26dcb 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -283,8 +283,12 @@ struct mga_device {
 
struct drm_plane primary_plane;
struct drm_crtc crtc;
-   struct drm_encoder encoder;
-   struct drm_connector connector;
+   struct {
+   struct {
+   struct drm_encoder encoder;
+   struct drm_connector connector;
+   } vga;
+   } output;
 };
 
 static inline struct mga_device *to_mga_device(struct drm_device *dev)
@@ -417,25 +421,15 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc 
*crtc, struct drm_crtc_st
.atomic_duplicate_state = mgag200_crtc_atomic_duplicate_state, \
.atomic_destroy_state = mgag200_crtc_atomic_destroy_state
 
-#define MGAG200_DAC_ENCODER_FUNCS \
-   .destroy = drm_encoder_cleanup
-
-#define MGAG200_VGA_CONNECTOR_HELPER_FUNCS \
-   .get_modes = drm_connector_helper_get_modes
-
-#define MGAG200_VGA_CONNECTOR_FUNCS \
-   .reset  = drm_atomic_helper_connector_reset, \
-   .fill_modes = drm_helper_probe_single_connector_modes, \
-   .destroy= drm_connector_cleanup, \
-   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state, \
-   .atomic_destroy_state   = drm_atomic_helper_connector_destroy_state
-
 void mgag200_set_mode_regs(struct mga_device *mdev, const struct 
drm_display_mode *mode);
 void mgag200_set_format_regs(struct mga_device *mdev, const struct 
drm_format_info *format);
 void mgag200_enable_display(struct mga_device *mdev);
 void mgag200_init_registers(struct mga_device *mdev);
 int mgag200_mode_config_init(struct mga_device *mdev, resource_size_t 
vram_available);
 
+/* mgag200_vga.c */
+int mgag200_vga_output_init(struct mga_device *mdev);
+
/* mgag200_bmc.c */
 void mgag200_bmc_disable_vidrst(struct mga_device *mdev);
 void mgag200_bmc_enable_vidrst(struct mga_device *mdev);
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c 
b/drivers/gpu/drm/mgag200/mgag200_g200.c
index 39a29d8ffca6e..ff467b0f9cbf3 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -9,7 +9,6 @@
 #include 
 #include 
 
-#include "mgag200_ddc.h"
 #include "mgag200_drv.h"
 
 static int mgag200_g200_init_pci_options(struct pci_dev *pdev)
@@ -184,26 +183,11 @@ static const struct drm_crtc_funcs 
mgag200_g200_crtc_funcs = {
MGAG200_CRTC_FUNCS,
 };
 
-static const struct drm_encoder_funcs mgag200_g200_dac_encoder_funcs = {
-   MGAG200_DAC_ENCODER_FUNCS,
-};
-
-static const struct drm_connector_helper_funcs 
mgag200_g200_vga_connector_helper_funcs = {
-   MGAG200_VGA_CONNECTOR_HELPER_FUNCS,
-};
-
-static const struct drm_connector_funcs mgag200_g200_vga_connector_funcs = {
-   MGAG200_VGA_CONNECTOR_FUNCS,
-};
-
 static int mgag200_g200_pipeline_init(struct mga_device *mdev)
 {
struct drm_device *dev = >base;
struct drm_plane *primary_plane = >primary_plane;
struct drm_crtc *crtc = >crtc;
-   struct drm_encoder *encoder = >encoder;
-   struct drm_connector *connector = >connector;
-   struct i2c_adapter *ddc;
int ret;
 
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -231,35 +215,9 @@ static int mgag200_g200_pip

[PATCH v2 2/3] drm/mgag200: Add BMC output

2024-06-10 Thread Thomas Zimmermann
The BMC output can be viewed via the BMC's web interface or a
similar client. Represent it as virtual encoder and connector.
It's attached to the same CRTC as the VGA connector.

The connector's status depends on the physical connector's status.
The BMC is only connected if the physical connector is not. This
is necessary to support userspace clients that can only handle a
single output per CRTC.

The BMC is a server feature. Add a BMC output for all server chips,
but not the desktop models.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_bmc.c | 107 ++
 drivers/gpu/drm/mgag200/mgag200_drv.h |  10 ++
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  |   4 +
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c |   4 +
 drivers/gpu/drm/mgag200/mgag200_g200er.c  |   4 +
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  |   4 +
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c |   4 +
 drivers/gpu/drm/mgag200/mgag200_g200se.c  |   4 +
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |   4 +
 9 files changed, 145 insertions(+)

diff --git a/drivers/gpu/drm/mgag200/mgag200_bmc.c 
b/drivers/gpu/drm/mgag200/mgag200_bmc.c
index 2ba2e3c5086a5..23ef85aa7e378 100644
--- a/drivers/gpu/drm/mgag200/mgag200_bmc.c
+++ b/drivers/gpu/drm/mgag200/mgag200_bmc.c
@@ -2,8 +2,18 @@
 
 #include 
 
+#include 
+#include 
+#include 
+#include 
+
 #include "mgag200_drv.h"
 
+static struct mgag200_bmc_connector *to_mgag200_bmc_connector(struct 
drm_connector *connector)
+{
+   return container_of(connector, struct mgag200_bmc_connector, base);
+}
+
 void mgag200_bmc_disable_vidrst(struct mga_device *mdev)
 {
u8 tmp;
@@ -97,3 +107,100 @@ void mgag200_bmc_enable_vidrst(struct mga_device *mdev)
tmp &= ~0x10;
WREG_DAC(MGA1064_GEN_IO_DATA, tmp);
 }
+
+static const struct drm_encoder_funcs mgag200_bmc_encoder_funcs = {
+   .destroy = drm_encoder_cleanup,
+};
+
+static int mgag200_bmc_connector_helper_detect_ctx(struct drm_connector 
*connector,
+  struct 
drm_modeset_acquire_ctx *ctx,
+  bool force)
+{
+   struct mgag200_bmc_connector *bmc_connector = 
to_mgag200_bmc_connector(connector);
+   struct drm_connector *physical_connector = 
bmc_connector->physical_connector;
+
+   /*
+* Most user-space compositors cannot handle more than one connected
+* connector per CRTC. Hence, we only mark the BMC as connected if the
+* physical connector is disconnected. If the physical connector's 
status
+* is connected or unknown, the BMC remains disconnected. This has no
+* effect on the output of the BMC.
+*
+* FIXME: Remove this logic once user-space compositors can handle more
+*than one connector per CRTC. The BMC should always be 
connected.
+*/
+
+   if (physical_connector && physical_connector->status == 
connector_status_disconnected)
+   return connector_status_connected;
+
+   return connector_status_disconnected;
+}
+
+static int mgag200_bmc_connector_helper_get_modes(struct drm_connector 
*connector)
+{
+   struct drm_device *dev = connector->dev;
+   struct mga_device *mdev = to_mga_device(dev);
+   const struct mgag200_device_info *minfo = mdev->info;
+
+   return drm_add_modes_noedid(connector, minfo->max_hdisplay, 
minfo->max_vdisplay);
+}
+
+static const struct drm_connector_helper_funcs 
mgag200_bmc_connector_helper_funcs = {
+   .get_modes = mgag200_bmc_connector_helper_get_modes,
+   .detect_ctx = mgag200_bmc_connector_helper_detect_ctx,
+};
+
+static const struct drm_connector_funcs mgag200_bmc_connector_funcs = {
+   .reset = drm_atomic_helper_connector_reset,
+   .fill_modes = drm_helper_probe_single_connector_modes,
+   .destroy = drm_connector_cleanup,
+   .atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
+   .atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
+};
+
+static int mgag200_bmc_connector_init(struct drm_device *dev,
+ struct mgag200_bmc_connector 
*bmc_connector,
+ struct drm_connector *physical_connector)
+{
+   struct drm_connector *connector = _connector->base;
+   int ret;
+
+   ret = drm_connector_init(dev, connector, _bmc_connector_funcs,
+DRM_MODE_CONNECTOR_VIRTUAL);
+   if (ret)
+   return ret;
+   drm_connector_helper_add(connector, 
_bmc_connector_helper_funcs);
+
+   bmc_connector->physical_connector = physical_connector;
+
+   return 0;
+}
+
+int mgag200_bmc_output_init(struct mga_device *mdev, struct drm_connector 
*physical_connector)
+{
+   struct drm_device *dev = >base;
+   struct drm_crtc *crtc = >crtc;
+   struct drm_encoder *encoder;
+   struct mgag200_bmc_co

[PATCH v2 3/3] drm/mgag200: Set .detect_ctx() and enable connector polling

2024-06-10 Thread Thomas Zimmermann
Set .detect_ctx() in struct drm_connector_helper_funcs to the
common helper drm_connector_helper_detect_from_ddc() and enable
polling for the connector. Mgag200 will now test for the monitor's
presence by probing the DDC in regular intervals.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_g200.c| 1 +
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  | 1 +
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 1 +
 drivers/gpu/drm/mgag200/mgag200_g200er.c  | 1 +
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  | 1 +
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 1 +
 drivers/gpu/drm/mgag200/mgag200_g200se.c  | 1 +
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  | 1 +
 drivers/gpu/drm/mgag200/mgag200_vga.c | 6 +-
 9 files changed, 13 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c 
b/drivers/gpu/drm/mgag200/mgag200_g200.c
index ff467b0f9cbf3..f874e29498409 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -401,6 +401,7 @@ struct mga_device *mgag200_g200_device_create(struct 
pci_dev *pdev, const struct
return ERR_PTR(ret);
 
drm_mode_config_reset(dev);
+   drm_kms_helper_poll_init(dev);
 
return mdev;
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c 
b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
index 6f31c5249f0b1..52bf49ead5c50 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
@@ -277,6 +277,7 @@ struct mga_device *mgag200_g200eh_device_create(struct 
pci_dev *pdev, const stru
return ERR_PTR(ret);
 
drm_mode_config_reset(dev);
+   drm_kms_helper_poll_init(dev);
 
return mdev;
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c 
b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
index 5befe8da4beb2..e7f89b2a59fd0 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh3.c
@@ -182,6 +182,7 @@ struct mga_device *mgag200_g200eh3_device_create(struct 
pci_dev *pdev,
return ERR_PTR(ret);
 
drm_mode_config_reset(dev);
+   drm_kms_helper_poll_init(dev);
 
return mdev;
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200er.c 
b/drivers/gpu/drm/mgag200/mgag200_g200er.c
index 55c275180cde2..4e8a1756138d7 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200er.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200er.c
@@ -316,6 +316,7 @@ struct mga_device *mgag200_g200er_device_create(struct 
pci_dev *pdev, const stru
return ERR_PTR(ret);
 
drm_mode_config_reset(dev);
+   drm_kms_helper_poll_init(dev);
 
return mdev;
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ev.c 
b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
index 2466126140db6..d884f3cb0ec79 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ev.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ev.c
@@ -321,6 +321,7 @@ struct mga_device *mgag200_g200ev_device_create(struct 
pci_dev *pdev, const stru
return ERR_PTR(ret);
 
drm_mode_config_reset(dev);
+   drm_kms_helper_poll_init(dev);
 
return mdev;
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c 
b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
index a52e60609c3de..839401e8b4654 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200ew3.c
@@ -202,6 +202,7 @@ struct mga_device *mgag200_g200ew3_device_create(struct 
pci_dev *pdev,
return ERR_PTR(ret);
 
drm_mode_config_reset(dev);
+   drm_kms_helper_poll_init(dev);
 
return mdev;
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200se.c 
b/drivers/gpu/drm/mgag200/mgag200_g200se.c
index 212770acdd477..a824bb8ad5791 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200se.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200se.c
@@ -521,6 +521,7 @@ struct mga_device *mgag200_g200se_device_create(struct 
pci_dev *pdev, const stru
return ERR_PTR(ret);
 
drm_mode_config_reset(dev);
+   drm_kms_helper_poll_init(dev);
 
return mdev;
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200wb.c 
b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
index cb6daa0426fbc..835df0f4fc13d 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200wb.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200wb.c
@@ -326,6 +326,7 @@ struct mga_device *mgag200_g200wb_device_create(struct 
pci_dev *pdev, const stru
return ERR_PTR(ret);
 
drm_mode_config_reset(dev);
+   drm_kms_helper_poll_init(dev);
 
return mdev;
 }
diff --git a/drivers/gpu/drm/mgag200/mgag200_vga.c 
b/drivers/gpu/drm/mgag200/mgag200_vga.c
index 6d8982990c2c3..60568f32736dd 100644
--- a/drivers/gpu/drm/mgag200/mgag200_vga.c
+++ b/drivers/gpu/drm/mgag200/mgag200_vga.c
@@ -12,7 +12,8 @@ static const struct drm_encoder_funcs 
mgag200_dac_encoder_funcs = {
 };
 
 static const struct drm_connector_helper_funcs 
mgag200_vga_connector_helper_funcs = {
-   .get_modes

[PATCH v2 0/3] drm/mgag200: Detect connector status

2024-06-10 Thread Thomas Zimmermann
Detect the connector status by polling the DDC. Update the status at
runtime. Add a dedicated BMC output to still display to the BMC while
the VGA connector is not attached.

This patchset fixes a long-standing problem where attaching the VGA
display a runtime resulted in incorrect display modes.

Tested on various Matrox hardware.

v2:
- move the DDC clean up into a separate patchset [1]
- add dedicated BMC support (Jocelyn)

[1] https://patchwork.freedesktop.org/series/133537/

Thomas Zimmermann (3):
  drm/mgag200: Consolidate VGA output
  drm/mgag200: Add BMC output
  drm/mgag200: Set .detect_ctx() and enable connector polling

 drivers/gpu/drm/mgag200/Makefile  |   3 +-
 drivers/gpu/drm/mgag200/mgag200_bmc.c | 107 ++
 drivers/gpu/drm/mgag200/mgag200_drv.h |  34 ---
 drivers/gpu/drm/mgag200/mgag200_g200.c|  47 +-
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  |  47 +-
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c |  47 +-
 drivers/gpu/drm/mgag200/mgag200_g200er.c  |  47 +-
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  |  47 +-
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c |  47 +-
 drivers/gpu/drm/mgag200/mgag200_g200se.c  |  47 +-
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  47 +-
 drivers/gpu/drm/mgag200/mgag200_vga.c |  72 +++
 12 files changed, 238 insertions(+), 354 deletions(-)
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_vga.c


base-commit: 2bea08bd31298d60d416b2a6ed346bb53dd28037
-- 
2.45.2



Re: [PATCH] drm/edid: reduce DisplayID log spamming

2024-06-10 Thread Thomas Zimmermann




Am 06.06.24 um 14:35 schrieb Jani Nikula:

Debug printing at DisplayID validation leads to lots of log spamming as
it's called at DisplayID iterators during EDID parsing. Remove it, and
replace with a less noisy message at connector EDID update.

Signed-off-by: Jani Nikula 


Acked-by: Thomas Zimmermann 


---
  drivers/gpu/drm/drm_displayid.c | 3 ---
  drivers/gpu/drm/drm_edid.c  | 5 +
  2 files changed, 5 insertions(+), 3 deletions(-)

diff --git a/drivers/gpu/drm/drm_displayid.c b/drivers/gpu/drm/drm_displayid.c
index 9d01d762801f..b4fd43783c50 100644
--- a/drivers/gpu/drm/drm_displayid.c
+++ b/drivers/gpu/drm/drm_displayid.c
@@ -33,9 +33,6 @@ validate_displayid(const u8 *displayid, int length, int idx)
if (IS_ERR(base))
return base;
  
-	DRM_DEBUG_KMS("base revision 0x%x, length %d, %d %d\n",

- base->rev, base->bytes, base->prod_id, base->ext_count);
-
/* +1 for DispID checksum */
dispid_length = sizeof(*base) + base->bytes + 1;
if (dispid_length > length - idx)
diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index f68a41eeb1fa..9fc7292f5382 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -6629,6 +6629,11 @@ static void update_displayid_info(struct drm_connector 
*connector,
  
  	displayid_iter_edid_begin(drm_edid, );

displayid_iter_for_each(block, ) {
+   drm_dbg_kms(connector->dev,
+   "[CONNECTOR:%d:%s] DisplayID extension version 0x%02x, 
primary use 0x%02x\n",
+   connector->base.id, connector->name,
+   displayid_version(),
+   displayid_primary_use());
if (displayid_version() == DISPLAY_ID_STRUCTURE_VER_20 &&
(displayid_primary_use() == 
PRIMARY_USE_HEAD_MOUNTED_VR ||
 displayid_primary_use() == 
PRIMARY_USE_HEAD_MOUNTED_AR))


--
--
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] drm/managed: Simplify if condition

2024-06-10 Thread Thomas Zimmermann




Am 05.06.24 um 13:50 schrieb Thorsten Blum:

The if condition !A || A && B can be simplified to !A || B.

Fixes the following Coccinelle/coccicheck warning reported by
excluded_middle.cocci:

WARNING !A || A && B is equivalent to !A || B

Compile-tested only.

Signed-off-by: Thorsten Blum 


Acked-by: Thomas Zimmermann 


---
  drivers/gpu/drm/drm_managed.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_managed.c b/drivers/gpu/drm/drm_managed.c
index 7646f67bda4e..79ce86a5bd67 100644
--- a/drivers/gpu/drm/drm_managed.c
+++ b/drivers/gpu/drm/drm_managed.c
@@ -197,7 +197,7 @@ void drmm_release_action(struct drm_device *dev,
spin_lock_irqsave(>managed.lock, flags);
list_for_each_entry_reverse(dr, >managed.resources, node.entry) {
if (dr->node.release == action) {
-   if (!data || (data && *(void **)dr->data == data)) {
+   if (!data || *(void **)dr->data == data) {
dr_match = dr;
del_dr(dev, dr_match);
        break;


--
--
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] drm/fbdev-dma: fix getting smem_start

2024-06-10 Thread Thomas Zimmermann

Hi

Am 04.06.24 um 10:03 schrieb Peng Fan (OSS):

From: Peng Fan 

If 'info->screen_buffer' locates in vmalloc address space, virt_to_page
will not be able to get correct results. With CONFIG_DEBUG_VM and
CONFIG_DEBUG_VIRTUAL enabled on ARM64, there is dump below:


Which graphics driver triggers this bug?


[3.536043] [ cut here ]
[3.540716] virt_to_phys used for non-linear address: 7fc4f540 
(0x800086001000)
[3.552628] WARNING: CPU: 4 PID: 61 at arch/arm64/mm/physaddr.c:12 
__virt_to_phys+0x68/0x98
[3.565455] Modules linked in:
[3.568525] CPU: 4 PID: 61 Comm: kworker/u12:5 Not tainted 
6.6.23-06226-g4986cc3e1b75-dirty #250
[3.577310] Hardware name: NXP i.MX95 19X19 board (DT)
[3.582452] Workqueue: events_unbound deferred_probe_work_func
[3.588291] pstate: 6049 (nZCv daif +PAN -UAO -TCO -DIT -SSBS BTYPE=--)
[3.595233] pc : __virt_to_phys+0x68/0x98
[3.599246] lr : __virt_to_phys+0x68/0x98
[3.603276] sp : 800083603990
[3.677939] Call trace:
[3.680393]  __virt_to_phys+0x68/0x98
[3.684067]  drm_fbdev_dma_helper_fb_probe+0x138/0x238
[3.689214]  __drm_fb_helper_initial_config_and_unlock+0x2b0/0x4c0
[3.695385]  drm_fb_helper_initial_config+0x4c/0x68
[3.700264]  drm_fbdev_dma_client_hotplug+0x8c/0xe0
[3.705161]  drm_client_register+0x60/0xb0
[3.709269]  drm_fbdev_dma_setup+0x94/0x148

So add a check 'is_vmalloc_addr'.

Fixes: b79fe9abd58b ("drm/fbdev-dma: Implement fbdev emulation for GEM DMA 
helpers")
Signed-off-by: Peng Fan 


Reviewed-by: Thomas Zimmermann 

Best regards
Thomas


---
  drivers/gpu/drm/drm_fbdev_dma.c | 7 ++-
  1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c
index 6c9427bb4053..9e2eddb6eb5c 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -130,7 +130,12 @@ static int drm_fbdev_dma_helper_fb_probe(struct 
drm_fb_helper *fb_helper,
info->flags |= FBINFO_READS_FAST; /* signal caching */
info->screen_size = sizes->surface_height * fb->pitches[0];
info->screen_buffer = map.vaddr;
-   info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer));
+
+   if (is_vmalloc_addr(info->screen_buffer))
+   info->fix.smem_start = 
page_to_phys(vmalloc_to_page(info->screen_buffer));
+   else
+   info->fix.smem_start = 
page_to_phys(virt_to_page(info->screen_buffer));
+
info->fix.smem_len = info->screen_size;
  
  	return 0;


--
--
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)



[PULL] drm-misc-fixes

2024-05-30 Thread Thomas Zimmermann
Hi Dave, Sima,

this is the PR for drm-misc-fixes or this week. FYI I had to run dim
pull-request with the -f option, so that it ignored the following error

dim: 779aa4d74785 ("drm/nouveau/nvif: Avoid build error due to potential 
integer overflows"): Fixes: SHA1 in not pointing at an ancestor:
dim: a61ddb4393ad ("drm: enable (most) W=1 warnings by default across the 
subsystem")
dim: ERROR: issues in commits detected, aborting

The commit a61ddb4393ad ("drm: enable (most) W=1 warnings by default
across the subsystem") apparently got in before the commit it fixes.

Best regards
Thomas

drm-misc-fixes-2024-05-30:
Short summary of fixes pull:

dma-buf:
- sw-sync: Don't interfere with IRQ handling
- Fix kthreads-handling error path

gem-shmem:
- Warn when trying to pin imported objects

lima:
- Fix dma_resv-related deadlock in object pin

msm:
- Remove build-time dependency on Python 3.9

nouveau:
- nvif: Fix possible integer overflow

panel:
- lg-sw43408: Select DP helpers; Declare backlight ops as static
- sitronix-st7789v: Various fixes for jt240mhqs_hwt_ek_e3 panel

panfrost:
- Fix dma_resv-related deadlock in object pin
The following changes since commit 3e049b6b8f32f25c6967f4cffd8eac6e1e5316f6:

  Merge tag 'drm-misc-fixes-2024-05-23' of 
https://gitlab.freedesktop.org/drm/misc/kernel into drm-fixes (2024-05-27 
13:47:14 +1000)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/misc/kernel.git 
tags/drm-misc-fixes-2024-05-30

for you to fetch changes up to bb195358806847217efba98de62b7decec3b371f:

  drm/msm: remove python 3.9 dependency for compiling msm (2024-05-30 18:49:23 
+0200)


Short summary of fixes pull:

dma-buf:
- sw-sync: Don't interfere with IRQ handling
- Fix kthreads-handling error path

gem-shmem:
- Warn when trying to pin imported objects

lima:
- Fix dma_resv-related deadlock in object pin

msm:
- Remove build-time dependency on Python 3.9

nouveau:
- nvif: Fix possible integer overflow

panel:
- lg-sw43408: Select DP helpers; Declare backlight ops as static
- sitronix-st7789v: Various fixes for jt240mhqs_hwt_ek_e3 panel

panfrost:
- Fix dma_resv-related deadlock in object pin


Abhinav Kumar (1):
  drm/msm: remove python 3.9 dependency for compiling msm

Adrián Larumbe (3):
  drm/panfrost: Fix dma_resv deadlock at drm object pin time
  drm/lima: Fix dma_resv deadlock at drm object pin time
  drm/gem-shmem: Add import attachment warning to locked pin function

Dmitry Baryshkov (2):
  drm/panel/lg-sw43408: select CONFIG_DRM_DISPLAY_DP_HELPER
  drm/panel/lg-sw43408: mark sw43408_backlight_ops as static

Fedor Pchelkin (1):
  dma-buf: handle testing kthreads creation failure

Gerald Loacker (3):
  drm/panel: sitronix-st7789v: fix timing for jt240mhqs_hwt_ek_e3 panel
  drm/panel: sitronix-st7789v: tweak timing for jt240mhqs_hwt_ek_e3 panel
  drm/panel: sitronix-st7789v: fix display size for jt240mhqs_hwt_ek_e3 
panel

Guenter Roeck (1):
  drm/nouveau/nvif: Avoid build error due to potential integer overflows

Maarten Lankhorst (1):
  Merge remote-tracking branch 'drm/drm-fixes' into drm-misc-fixes

Tetsuo Handa (1):
  dma-buf/sw-sync: don't enable IRQ from sync_print_obj()

 drivers/dma-buf/st-dma-fence.c |  6 ++
 drivers/dma-buf/sync_debug.c   |  4 ++--
 drivers/gpu/drm/drm_gem_shmem_helper.c |  2 ++
 drivers/gpu/drm/lima/lima_gem.c|  2 +-
 drivers/gpu/drm/msm/registers/gen_header.py|  5 +++--
 drivers/gpu/drm/nouveau/nvif/object.c  | 24 ++--
 drivers/gpu/drm/panel/Kconfig  |  2 ++
 drivers/gpu/drm/panel/panel-lg-sw43408.c   |  2 +-
 drivers/gpu/drm/panel/panel-sitronix-st7789v.c | 16 
 drivers/gpu/drm/panfrost/panfrost_gem.c|  2 +-
 10 files changed, 44 insertions(+), 21 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)


[PULL] drm-misc-fixes

2024-05-23 Thread Thomas Zimmermann
Hi Dave, Sima,

here's the weekly PR for drm-misc-fixes. There's one important
patch included, which fixes a kernel panic that can be triggered
from userspace.

Best regards
Thomas

drm-misc-fixes-2024-05-23:
Short summary of fixes pull:

buddy:
- stop using PAGE_SIZE

shmem-helper:
- avoid kernel panic in mmap()

tests:
- buddy: fix PAGE_SIZE dependency
The following changes since commit 6897204ea3df808d342c8e4613135728bc538bcd:

  drm/connector: Add \n to message about demoting connector force-probes 
(2024-05-07 09:17:07 -0700)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/misc/kernel.git 
tags/drm-misc-fixes-2024-05-23

for you to fetch changes up to 39bc27bd688066a63e56f7f64ad34fae03fbe3b8:

  drm/shmem-helper: Fix BUG_ON() on mmap(PROT_WRITE, MAP_PRIVATE) (2024-05-21 
14:38:51 +0200)


Short summary of fixes pull:

buddy:
- stop using PAGE_SIZE

shmem-helper:
- avoid kernel panic in mmap()

tests:
- buddy: fix PAGE_SIZE dependency


Matthew Auld (2):
  drm/buddy: stop using PAGE_SIZE
  drm/tests/buddy: stop using PAGE_SIZE

Mohamed Ahmed (1):
  drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations

Wachowski, Karol (1):
  drm/shmem-helper: Fix BUG_ON() on mmap(PROT_WRITE, MAP_PRIVATE)

 drivers/gpu/drm/drm_buddy.c |  2 +-
 drivers/gpu/drm/drm_gem_shmem_helper.c  |  3 +++
 drivers/gpu/drm/nouveau/nouveau_abi16.c |  3 +++
 drivers/gpu/drm/nouveau/nouveau_bo.c| 44 ++---
 drivers/gpu/drm/tests/drm_buddy_test.c  | 42 +++
 include/drm/drm_buddy.h |  6 ++---
 include/uapi/drm/nouveau_drm.h  |  7 ++
 7 files changed, 57 insertions(+), 50 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)


Re: [PATCH v2 2/2] drm/mgag200: Add an option to disable Write-Combine

2024-05-17 Thread Thomas Zimmermann

Hi

Am 17.05.24 um 17:09 schrieb Jocelyn Falempe:

Unfortunately, the G200 ioburst workaround doesn't work on some
servers like Dell poweredge XR11, XR5610, or HPE XL260. In this case
completely disabling WC is the only option to achieve low-latency.
So this adds a new Kconfig option to disable WC mapping of the G200.

Signed-off-by: Jocelyn Falempe 


Reviewed-by: Thomas Zimmermann 

Thanks a lot for the fix.

Best regards
Thomas


---
  drivers/gpu/drm/mgag200/Kconfig   | 10 ++
  drivers/gpu/drm/mgag200/mgag200_drv.c |  6 ++
  2 files changed, 16 insertions(+)

diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig
index b28c5e4828f47..3096944a8f0ab 100644
--- a/drivers/gpu/drm/mgag200/Kconfig
+++ b/drivers/gpu/drm/mgag200/Kconfig
@@ -11,3 +11,13 @@ config DRM_MGAG200
 MGA G200 desktop chips and the server variants. It requires 0.3.0
 of the modesetting userspace driver, and a version of mga driver
 that will fail on KMS enabled devices.
+
+config DRM_MGAG200_DISABLE_WRITECOMBINE
+   bool "Disable Write Combine mapping of VRAM"
+   depends on DRM_MGAG200 && PREEMPT_RT
+   help
+ The VRAM of the G200 is mapped with Write-Combine to improve
+ performances. This can interfere with real-time tasks; even if they
+ are running on other CPU cores than the graphics output.
+ Enable this option only if you run realtime tasks on a server with a
+ Matrox G200.
\ No newline at end of file
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c 
b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 3883f25ca4d8b..62080cf0f2da4 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -146,12 +146,18 @@ int mgag200_device_preinit(struct mga_device *mdev)
}
mdev->vram_res = res;
  
+#if defined(CONFIG_DRM_MGAG200_DISABLE_WRITECOMBINE)

+   mdev->vram = devm_ioremap(dev->dev, res->start, resource_size(res));
+   if (!mdev->vram)
+   return -ENOMEM;
+#else
mdev->vram = devm_ioremap_wc(dev->dev, res->start, resource_size(res));
if (!mdev->vram)
return -ENOMEM;
  
  	/* Don't fail on errors, but performance might be reduced. */

devm_arch_phys_wc_add(dev->dev, res->start, resource_size(res));
+#endif
  
  	return 0;

  }


--
--
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 2/2] drm/mgag200: Add an option to disable Write-Combine

2024-05-17 Thread Thomas Zimmermann

Hi,

just nits below.

Am 16.05.24 um 18:17 schrieb Jocelyn Falempe:

Unfortunately, the G200 ioburst workaround doesn't work on some servers
like Dell poweredge XR11, XR5610, or HPE XL260
In this case completely disabling WC is the only option to achieve
low-latency.
So this adds a new Kconfig option, to disable WC mapping of the G200


The formatting look off. Maybe make this one single paragraph.

No comma after 'option'.



Signed-off-by: Jocelyn Falempe 
---
  drivers/gpu/drm/mgag200/Kconfig   | 10 ++
  drivers/gpu/drm/mgag200/mgag200_drv.c |  7 +++
  2 files changed, 17 insertions(+)

diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig
index b28c5e4828f47..73ab5730b74d9 100644
--- a/drivers/gpu/drm/mgag200/Kconfig
+++ b/drivers/gpu/drm/mgag200/Kconfig
@@ -11,3 +11,13 @@ config DRM_MGAG200
 MGA G200 desktop chips and the server variants. It requires 0.3.0
 of the modesetting userspace driver, and a version of mga driver
 that will fail on KMS enabled devices.
+
+config DRM_MGAG200_DISABLE_WRITECOMBINE
+   bool "Disable Write Combine mapping of VRAM"
+   depends on DRM_MGAG200 && PREEMPT_RT
+   help
+ The VRAM of the G200 is mapped with Write-Combine, to improve

No comma after Write-Combine

+ performances. However this increases the system latency a lot, even
Just say "This can interfere with real-time tasks; even if they are 
running on other CPU cores then the graphics output."



+ for realtime tasks running on other CPU cores. Typically 40us-80us
+ latencies are measured with hwlat when Write Combine is enabled.


Leave out the next sentence: "Typically ..." The measureed numbers 
depend on the hardware and everyone is encouraged to test on their own 
system. You could mention  the numbers in the commit description, as you 
already mention the affected systems there.



+ Recommended if you run realtime tasks on a server with a Matrox G200.


I still think that we should not encourage anyone to use this option. 
Maybe say "Enable this option only if you run..."



\ No newline at end of file
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.c 
b/drivers/gpu/drm/mgag200/mgag200_drv.c
index 3883f25ca4d8b..7461e3f984eff 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.c
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.c
@@ -146,12 +146,19 @@ int mgag200_device_preinit(struct mga_device *mdev)
}
mdev->vram_res = res;
  
+#if defined(CONFIG_DRM_MGAG200_DISABLE_WRITECOMBINE)

+   drm_info(dev, "Disable Write Combine\n");


I would not print this drm_info() here. The user has selected the config 
option, so they should know what happens. It's also listed in /proc/mtrr 
IIRC.


Best regards
Thomas


+   mdev->vram = devm_ioremap(dev->dev, res->start, resource_size(res));
+   if (!mdev->vram)
+   return -ENOMEM;
+#else
mdev->vram = devm_ioremap_wc(dev->dev, res->start, resource_size(res));
if (!mdev->vram)
return -ENOMEM;
  
  	/* Don't fail on errors, but performance might be reduced. */

devm_arch_phys_wc_add(dev->dev, res->start, resource_size(res));
+#endif
  
  	return 0;

  }


--
--
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 1/2] Revert "drm/mgag200: Add a workaround for low-latency"

2024-05-17 Thread Thomas Zimmermann




Am 16.05.24 um 18:17 schrieb Jocelyn Falempe:

This reverts commit bfa4437fd3938ae2e186e7664b2db65bb8775670.

This workaround doesn't work reliably on all servers.
I'll replace it with an option to disable Write-Combine,
which has more impact on performance, but fix the latency
issue on all hardware.

Signed-off-by: Jocelyn Falempe 


Reviewed-by: Thomas Zimmermann 


---
  drivers/gpu/drm/mgag200/Kconfig| 12 
  drivers/gpu/drm/mgag200/mgag200_drv.c  | 17 -
  drivers/gpu/drm/mgag200/mgag200_mode.c |  8 
  3 files changed, 37 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/Kconfig b/drivers/gpu/drm/mgag200/Kconfig
index 5e4d48df4854c..b28c5e4828f47 100644
--- a/drivers/gpu/drm/mgag200/Kconfig
+++ b/drivers/gpu/drm/mgag200/Kconfig
@@ -11,15 +11,3 @@ config DRM_MGAG200
 MGA G200 desktop chips and the server variants. It requires 0.3.0
 of the modesetting userspace driver, and a version of mga driver
 that will fail on KMS enabled devices.
-
-config DRM_MGAG200_IOBURST_WORKAROUND
-   bool "Disable buffer caching"
-   depends on DRM_MGAG200 && PREEMPT_RT && X86
-   help
- Enable a workaround to avoid I/O bursts within the mgag200 driver at
- the expense of overall display performance.
- It restores the   
-#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND)

-static struct drm_gem_object *mgag200_create_object(struct drm_device *dev, 
size_t size)
-{
-   struct drm_gem_shmem_object *shmem;
-
-   shmem = kzalloc(sizeof(*shmem), GFP_KERNEL);
-   if (!shmem)
-   return NULL;
-
-   shmem->map_wc = true;
-   return >base;
-}
-#endif
-
  /*
   * DRM driver
   */
@@ -113,9 +99,6 @@ static const struct drm_driver mgag200_driver = {
.major = DRIVER_MAJOR,
.minor = DRIVER_MINOR,
.patchlevel = DRIVER_PATCHLEVEL,
-#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND)
-   .gem_create_object = mgag200_create_object,
-#endif
DRM_GEM_SHMEM_DRIVER_OPS,
  };
  
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c b/drivers/gpu/drm/mgag200/mgag200_mode.c

index fc54851d3384d..d3d820f7a77d7 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -13,7 +13,6 @@
  
  #include 

  #include 
-#include 
  #include 
  #include 
  #include 
@@ -438,13 +437,6 @@ static void mgag200_handle_damage(struct mga_device *mdev, 
const struct iosys_ma
  
  	iosys_map_incr(, drm_fb_clip_offset(fb->pitches[0], fb->format, clip));

drm_fb_memcpy(, fb->pitches, vmap, fb, clip);
-
-   /* Flushing the cache greatly improves latency on x86_64 */
-#if defined(CONFIG_DRM_MGAG200_IOBURST_WORKAROUND)
-   if (!vmap->is_iomem)
-   drm_clflush_virt_range(vmap->vaddr + clip->y1 * fb->pitches[0],
-  drm_rect_height(clip) * fb->pitches[0]);
-#endif
  }
  
  /*


--
--
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)



[PATCH] arch: Fix name collision with ACPI's video.o

2024-05-17 Thread Thomas Zimmermann
Commit 2fd001cd3600 ("arch: Rename fbdev header and source files")
renames the video source files under arch/ such that they do not
refer to fbdev any longer. The new files named video.o conflict with
ACPI's video.ko module. Modprobing the ACPI module can then fail with
warnings about missing symbols, as shown below.

  (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol 
acpi_video_unregister (err -2)
  (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol 
acpi_video_register_backlight (err -2)
  (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol 
__acpi_video_get_backlight_type (err -2)
  (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol 
acpi_video_register (err -2)

Fix the issue by renaming the architecture's video.o to video-common.o.

Reported-by: Chaitanya Kumar Borah 
Closes: 
https://lore.kernel.org/intel-gfx/9dcac6e9-a3bf-4ace-bbdc-f697f767f...@suse.de/T/#t
Signed-off-by: Thomas Zimmermann 
Fixes: 2fd001cd3600 ("arch: Rename fbdev header and source files")
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
---
 arch/sparc/video/Makefile| 2 +-
 arch/sparc/video/{video.c => video-common.c} | 0
 arch/x86/video/Makefile  | 2 +-
 arch/x86/video/{video.c => video-common.c}   | 0
 4 files changed, 2 insertions(+), 2 deletions(-)
 rename arch/sparc/video/{video.c => video-common.c} (100%)
 rename arch/x86/video/{video.c => video-common.c} (100%)

diff --git a/arch/sparc/video/Makefile b/arch/sparc/video/Makefile
index fdf83a408d750..dcfbe7a5912c0 100644
--- a/arch/sparc/video/Makefile
+++ b/arch/sparc/video/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-obj-y  += video.o
+obj-y  += video-common.o
diff --git a/arch/sparc/video/video.c b/arch/sparc/video/video-common.c
similarity index 100%
rename from arch/sparc/video/video.c
rename to arch/sparc/video/video-common.c
diff --git a/arch/x86/video/Makefile b/arch/x86/video/Makefile
index fdf83a408d750..dcfbe7a5912c0 100644
--- a/arch/x86/video/Makefile
+++ b/arch/x86/video/Makefile
@@ -1,3 +1,3 @@
 # SPDX-License-Identifier: GPL-2.0-only
 
-obj-y  += video.o
+obj-y  += video-common.o
diff --git a/arch/x86/video/video.c b/arch/x86/video/video-common.c
similarity index 100%
rename from arch/x86/video/video.c
rename to arch/x86/video/video-common.c
-- 
2.45.0



Re: [PATCH] ACPI: video: Fix name collision with architecture's video.o

2024-05-16 Thread Thomas Zimmermann

Hi

Am 16.05.24 um 17:03 schrieb Hans de Goede:

Hi,

On 5/16/24 3:04 PM, Rafael J. Wysocki wrote:

CC Hans who has been doing the majority of the ACPI video work.

On Thu, May 16, 2024 at 2:43 PM Thomas Zimmermann  wrote:

Commit 2fd001cd3600 ("arch: Rename fbdev header and source files")
renames the video source files under arch/ such that they does not
refer to fbdev any longer. The new files named video.o conflict with
ACPI's video.ko module.

And surely nobody knew or was unable to check upfront that there was a
video.ko already in the kernel.

Sorry, but nack for this change. I very deliberately kept the module-name
as video when renaming the actual .c file from video.c to acpi_video.c
because many people pass drivers/video/acpi_video.c module arguments
on the kernel commandline using video.param=val .

Try e.g. doing a duckduckgo search for 1 off:

"video.only_lcd"
"video.allow_duplicates"
"video.brightness_switch_enabled"


Ok, that makes sense. I'll rename the other files.

Best regards
Thomas



And you will find a lot of hits. The last one is even documented as
being "video.brightness_switch_enabled" in the main kernel-parameters.txt
as well as separately:

https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/kernel-parameters.txt#n39
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/admin-guide/kernel-parameters.txt#n7152
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/Documentation/firmware-guide/acpi/video_extension.rst#n118

https://wiki.archlinux.org/title/Lenovo_ThinkPad_X1_Carbon#Brightness_control

If you rename this module then peoples config will break for
a whole lot of users.

So lets not do that and lets rename the new module which is causing
the conflict in the first place instead.

Regards,

Hans



--
--
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)



[PATCH] ACPI: video: Fix name collision with architecture's video.o

2024-05-16 Thread Thomas Zimmermann
Commit 2fd001cd3600 ("arch: Rename fbdev header and source files")
renames the video source files under arch/ such that they does not
refer to fbdev any longer. The new files named video.o conflict with
ACPI's video.ko module. Modprobing the ACPI module can then fail with
warnings about missing symbols, as shown below.

  (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol 
acpi_video_unregister (err -2)
  (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol 
acpi_video_register_backlight (err -2)
  (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol 
__acpi_video_get_backlight_type (err -2)
  (i915_selftest:1107) igt_kmod-WARNING: i915: Unknown symbol 
acpi_video_register (err -2)

Fix this problem by renaming ACPI's video.ko to acpi_video.ko. Also
rename a related source file and clean up the Makefile.

Reported-by: Chaitanya Kumar Borah 
Closes: 
https://lore.kernel.org/intel-gfx/9dcac6e9-a3bf-4ace-bbdc-f697f767f...@suse.de/T/#t
Tested-by: Chaitanya Kumar Borah 
Signed-off-by: Thomas Zimmermann 
Fixes: 2fd001cd3600 ("arch: Rename fbdev header and source files")
Cc: Arnd Bergmann 
Cc: linux-a...@vger.kernel.org
Cc: linux-fb...@vger.kernel.org
Cc: dri-devel@lists.freedesktop.org
---
 drivers/acpi/Makefile| 5 +++--
 drivers/acpi/{acpi_video.c => acpi_video_core.c} | 2 +-
 2 files changed, 4 insertions(+), 3 deletions(-)
 rename drivers/acpi/{acpi_video.c => acpi_video_core.c} (99%)

diff --git a/drivers/acpi/Makefile b/drivers/acpi/Makefile
index 8cc8c0d9c8732..fc9e11f7afbf7 100644
--- a/drivers/acpi/Makefile
+++ b/drivers/acpi/Makefile
@@ -84,7 +84,9 @@ obj-$(CONFIG_ACPI_FAN)+= fan.o
 fan-objs   := fan_core.o
 fan-objs   += fan_attr.o
 
-obj-$(CONFIG_ACPI_VIDEO)   += video.o
+obj-$(CONFIG_ACPI_VIDEO)   += acpi_video.o
+acpi_video-objs+= acpi_video_core.o video_detect.o
+
 obj-$(CONFIG_ACPI_TAD) += acpi_tad.o
 obj-$(CONFIG_ACPI_PCI_SLOT)+= pci_slot.o
 obj-$(CONFIG_ACPI_PROCESSOR)   += processor.o
@@ -124,7 +126,6 @@ obj-$(CONFIG_ACPI_CONFIGFS) += acpi_configfs.o
 
 obj-y  += pmic/
 
-video-objs += acpi_video.o video_detect.o
 obj-y  += dptf/
 
 obj-$(CONFIG_ARM64)+= arm64/
diff --git a/drivers/acpi/acpi_video.c b/drivers/acpi/acpi_video_core.c
similarity index 99%
rename from drivers/acpi/acpi_video.c
rename to drivers/acpi/acpi_video_core.c
index 1fda303882973..32bf81c5773a4 100644
--- a/drivers/acpi/acpi_video.c
+++ b/drivers/acpi/acpi_video_core.c
@@ -1,6 +1,6 @@
 // SPDX-License-Identifier: GPL-2.0-or-later
 /*
- *  video.c - ACPI Video Driver
+ *  acpi_video_core.c - ACPI Video Driver
  *
  *  Copyright (C) 2004 Luming Yu 
  *  Copyright (C) 2004 Bruno Ducrot 
-- 
2.45.0



Re: [PATCH 00/10] drm/mgag200: Refactor DDC code

2024-05-16 Thread Thomas Zimmermann

Hi

Am 16.05.24 um 11:14 schrieb Jocelyn Falempe:

Thanks for this refactor of mgag200.

for the whole series:

Reviewed-by: Jocelyn Falempe 



Thank you so much!

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)



[PULL] drm-misc-fixes

2024-05-16 Thread Thomas Zimmermann
Hi Dave, Sima

there's only a single patch in this week's drm-misc-fixes PR.

Best regards
Thomas

drm-misc-fixes-2024-05-16:
Short summary of fixes pull:

nouveau:
- use tile_mode and pte_kind for VM_BIND bo allocations
The following changes since commit 6897204ea3df808d342c8e4613135728bc538bcd:

  drm/connector: Add \n to message about demoting connector force-probes 
(2024-05-07 09:17:07 -0700)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/misc/kernel.git 
tags/drm-misc-fixes-2024-05-16

for you to fetch changes up to aed9a1a4f7106ff99a882ad06318cebfa71016a2:

  drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations 
(2024-05-13 22:17:58 +0200)


Short summary of fixes pull:

nouveau:
- use tile_mode and pte_kind for VM_BIND bo allocations


Mohamed Ahmed (1):
  drm/nouveau: use tile_mode and pte_kind for VM_BIND bo allocations

 drivers/gpu/drm/nouveau/nouveau_abi16.c |  3 +++
 drivers/gpu/drm/nouveau/nouveau_bo.c| 44 ++---
 include/uapi/drm/nouveau_drm.h  |  7 ++
 3 files changed, 29 insertions(+), 25 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)


Re: [PATCH] drm/fbdev-dma: Clean up deferred I/O

2024-05-15 Thread Thomas Zimmermann




Am 15.05.24 um 13:59 schrieb Javier Martinez Canillas:

Thomas Zimmermann  writes:


Call fb_deferred_io_cleanup() upon destroying the framebuffer
device. Releases the internal memory.

Signed-off-by: Thomas Zimmermann 
Fixes: 808a40b69468 ("drm/fbdev-dma: Implement damage handling and deferred 
I/O")
Cc: Thomas Zimmermann 
Cc: Javier Martinez Canillas 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
---
  drivers/gpu/drm/drm_fbdev_dma.c | 1 +
  1 file changed, 1 insertion(+)

Reviewed-by: Javier Martinez Canillas 


Thanks a lot. I've pushed this patch and the other one to drm-misc-next.





--
--
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 05/11] drm/hisilicon/hibmc: convert to struct drm_edid

2024-05-15 Thread Thomas Zimmermann

Hi

Am 15.05.24 um 14:34 schrieb Jani Nikula:

On Tue, 14 May 2024, Thomas Zimmermann  wrote:

Hi

Am 14.05.24 um 14:55 schrieb Jani Nikula:

Prefer the struct drm_edid based functions for reading the EDID and
updating the connector.

Signed-off-by: Jani Nikula 

---

Cc: Xinliang Liu 
Cc: Tian Tao 
Cc: Xinwei Kong 
Cc: Sumit Semwal 
Cc: Yongqin Liu 
Cc: John Stultz 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
---
   .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c| 17 ++---
   1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c 
b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 94e2c573a7af..409c551c92af 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -24,14 +24,16 @@
   
   static int hibmc_connector_get_modes(struct drm_connector *connector)

Could this function be replaced with a call to
drm_connector_helper_get_modes()? With the patch, the only difference is
the call to the _noedid() function, which the DRM core does
automatically. There will still be a difference in the maximum
resolution, but standardizing on 1024x768 seems preferable to me.

Looks like it might work, but personally, I'm trying to shy away from
any further cleanups than just switching to struct drm_edid. I've got my
plate pretty full already.


In that case

Reviewed-by: Thomas Zimmermann 

for the current patch.

Best regards
Thomas



BR,
Jani.



Best regards
Thomas


   {
-   int count;
-   void *edid;
struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector);
+   const struct drm_edid *drm_edid;
+   int count;
+
+   drm_edid = drm_edid_read_ddc(connector, _connector->adapter);
   
-	edid = drm_get_edid(connector, _connector->adapter);

-   if (edid) {
-   drm_connector_update_edid_property(connector, edid);
-   count = drm_add_edid_modes(connector, edid);
+   drm_edid_connector_update(connector, drm_edid);
+
+   if (drm_edid) {
+   count = drm_edid_connector_add_modes(connector);
if (count)
goto out;
}
@@ -42,7 +44,8 @@ static int hibmc_connector_get_modes(struct drm_connector 
*connector)
drm_set_preferred_mode(connector, 1024, 768);
   
   out:

-   kfree(edid);
+   drm_edid_free(drm_edid);
+
return count;
   }
   


--
--
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 05/11] drm/hisilicon/hibmc: convert to struct drm_edid

2024-05-14 Thread Thomas Zimmermann

Hi

Am 14.05.24 um 14:55 schrieb Jani Nikula:

Prefer the struct drm_edid based functions for reading the EDID and
updating the connector.

Signed-off-by: Jani Nikula 

---

Cc: Xinliang Liu 
Cc: Tian Tao 
Cc: Xinwei Kong 
Cc: Sumit Semwal 
Cc: Yongqin Liu 
Cc: John Stultz 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
---
  .../gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c| 17 ++---
  1 file changed, 10 insertions(+), 7 deletions(-)

diff --git a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c 
b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
index 94e2c573a7af..409c551c92af 100644
--- a/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
+++ b/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c
@@ -24,14 +24,16 @@
  
  static int hibmc_connector_get_modes(struct drm_connector *connector)


Could this function be replaced with a call to 
drm_connector_helper_get_modes()? With the patch, the only difference is 
the call to the _noedid() function, which the DRM core does 
automatically. There will still be a difference in the maximum 
resolution, but standardizing on 1024x768 seems preferable to me.


Best regards
Thomas


  {
-   int count;
-   void *edid;
struct hibmc_connector *hibmc_connector = to_hibmc_connector(connector);
+   const struct drm_edid *drm_edid;
+   int count;
+
+   drm_edid = drm_edid_read_ddc(connector, _connector->adapter);
  
-	edid = drm_get_edid(connector, _connector->adapter);

-   if (edid) {
-   drm_connector_update_edid_property(connector, edid);
-   count = drm_add_edid_modes(connector, edid);
+   drm_edid_connector_update(connector, drm_edid);
+
+   if (drm_edid) {
+   count = drm_edid_connector_add_modes(connector);
if (count)
goto out;
}
@@ -42,7 +44,8 @@ static int hibmc_connector_get_modes(struct drm_connector 
*connector)
drm_set_preferred_mode(connector, 1024, 768);
  
  out:

-   kfree(edid);
+   drm_edid_free(drm_edid);
+
return count;
  }
  


--
--
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: drm: Remove driver dependencies on FB_DEVICE

2024-05-14 Thread Thomas Zimmermann

Hi

Am 14.05.24 um 14:34 schrieb Manas Ghandat:
Hi. I recently looked at the todos of drm and found the topic 
interesting. I wanted to get started with this issue but having some 
trouble identifying the devices. What would be the right approach to 
get started?


Sorry, there's already someone working on that topic.

Best regards
Thomas



Thanks,

Manas



--
--
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] drm/edid: remove drm_do_get_edid()

2024-05-14 Thread Thomas Zimmermann




Am 13.05.24 um 22:27 schrieb Jani Nikula:

All users of drm_do_get_edid() have been converted to
drm_edid_read_custom(). Remove the unused function to prevent new users
from creeping in.

Signed-off-by: Jani Nikula 


Reviewed-by: Thomas Zimmermann 



---

Cc: Robert Foss 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
---
  drivers/gpu/drm/drm_edid.c | 28 
  include/drm/drm_edid.h |  4 
  2 files changed, 32 deletions(-)

diff --git a/drivers/gpu/drm/drm_edid.c b/drivers/gpu/drm/drm_edid.c
index 4f54c91b31b2..0f7c4c5b14b9 100644
--- a/drivers/gpu/drm/drm_edid.c
+++ b/drivers/gpu/drm/drm_edid.c
@@ -2464,34 +2464,6 @@ static struct edid *_drm_do_get_edid(struct 
drm_connector *connector,
return NULL;
  }
  
-/**

- * drm_do_get_edid - get EDID data using a custom EDID block read function
- * @connector: connector we're probing
- * @read_block: EDID block read function
- * @context: private data passed to the block read function
- *
- * When the I2C adapter connected to the DDC bus is hidden behind a device that
- * exposes a different interface to read EDID blocks this function can be used
- * to get EDID data using a custom block read function.
- *
- * As in the general case the DDC bus is accessible by the kernel at the I2C
- * level, drivers must make all reasonable efforts to expose it as an I2C
- * adapter and use drm_get_edid() instead of abusing this function.
- *
- * The EDID may be overridden using debugfs override_edid or firmware EDID
- * (drm_edid_load_firmware() and drm.edid_firmware parameter), in this priority
- * order. Having either of them bypasses actual EDID reads.
- *
- * Return: Pointer to valid EDID or NULL if we couldn't find any.
- */
-struct edid *drm_do_get_edid(struct drm_connector *connector,
-read_block_fn read_block,
-void *context)
-{
-   return _drm_do_get_edid(connector, read_block, context, NULL);
-}
-EXPORT_SYMBOL_GPL(drm_do_get_edid);
-
  /**
   * drm_edid_raw - Get a pointer to the raw EDID data.
   * @drm_edid: drm_edid container
diff --git a/include/drm/drm_edid.h b/include/drm/drm_edid.h
index b085525e53e2..6bdfa254a1c1 100644
--- a/include/drm/drm_edid.h
+++ b/include/drm/drm_edid.h
@@ -423,10 +423,6 @@ static inline void drm_edid_decode_panel_id(u32 panel_id, 
char vend[4], u16 *pro
  }
  
  bool drm_probe_ddc(struct i2c_adapter *adapter);

-struct edid *drm_do_get_edid(struct drm_connector *connector,
-   int (*get_edid_block)(void *data, u8 *buf, unsigned int block,
- size_t len),
-   void *data);
  struct edid *drm_get_edid(struct drm_connector *connector,
  struct i2c_adapter *adapter);
  struct edid *drm_get_edid_switcheroo(struct drm_connector *connector,


--
--
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)



[PATCH 04/10] drm/mgag200: Allocate instance of struct mga_i2c_chan dynamically

2024-05-13 Thread Thomas Zimmermann
Allocate instances of struct mga_i2c_chan in mgag200_ddc_create()
and return a pointer to the contained i2c adapter. The callers of
the function are now independent from struct mga_i2c_chan.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_ddc.h | 11 +++
 drivers/gpu/drm/mgag200/mgag200_drv.h |  4 
 drivers/gpu/drm/mgag200/mgag200_g200.c| 11 ++-
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  | 11 ++-
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c | 11 ++-
 drivers/gpu/drm/mgag200/mgag200_g200er.c  | 11 ++-
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  | 11 ++-
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c | 11 ++-
 drivers/gpu/drm/mgag200/mgag200_g200se.c  | 11 ++-
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  | 11 ++-
 drivers/gpu/drm/mgag200/mgag200_i2c.c | 20 +++-
 drivers/gpu/drm/mgag200/mgag200_mode.c|  1 +
 12 files changed, 79 insertions(+), 45 deletions(-)
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_ddc.h

diff --git a/drivers/gpu/drm/mgag200/mgag200_ddc.h 
b/drivers/gpu/drm/mgag200/mgag200_ddc.h
new file mode 100644
index 0..fa21d197cc783
--- /dev/null
+++ b/drivers/gpu/drm/mgag200/mgag200_ddc.h
@@ -0,0 +1,11 @@
+/* SPDX-License-Identifier: GPL-2.0-only */
+
+#ifndef __MGAG200_DDC_H__
+#define __MGAG200_DDC_H__
+
+struct i2c_adapter;
+struct mga_device;
+
+struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev);
+
+#endif
diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h 
b/drivers/gpu/drm/mgag200/mgag200_drv.h
index c7d4047301bfb..3c834bfd82cf4 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -294,7 +294,6 @@ struct mga_device {
struct drm_plane primary_plane;
struct drm_crtc crtc;
struct drm_encoder encoder;
-   struct mga_i2c_chan i2c;
struct drm_connector connector;
 };
 
@@ -453,7 +452,4 @@ int mgag200_mode_config_init(struct mga_device *mdev, 
resource_size_t vram_avail
 void mgag200_bmc_disable_vidrst(struct mga_device *mdev);
 void mgag200_bmc_enable_vidrst(struct mga_device *mdev);
 
-   /* mgag200_i2c.c */
-int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c);
-
 #endif /* __MGAG200_DRV_H__ */
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200.c 
b/drivers/gpu/drm/mgag200/mgag200_g200.c
index bf5d7fe525a3f..39a29d8ffca6e 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 
+#include "mgag200_ddc.h"
 #include "mgag200_drv.h"
 
 static int mgag200_g200_init_pci_options(struct pci_dev *pdev)
@@ -201,8 +202,8 @@ static int mgag200_g200_pipeline_init(struct mga_device 
*mdev)
struct drm_plane *primary_plane = >primary_plane;
struct drm_crtc *crtc = >crtc;
struct drm_encoder *encoder = >encoder;
-   struct mga_i2c_chan *i2c = >i2c;
struct drm_connector *connector = >connector;
+   struct i2c_adapter *ddc;
int ret;
 
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -238,16 +239,16 @@ static int mgag200_g200_pipeline_init(struct mga_device 
*mdev)
return ret;
}
 
-   ret = mgag200_i2c_init(mdev, i2c);
-   if (ret) {
+   ddc = mgag200_ddc_create(mdev);
+   if (IS_ERR(ddc)) {
+   ret = PTR_ERR(ddc);
drm_err(dev, "failed to add DDC bus: %d\n", ret);
return ret;
}
 
ret = drm_connector_init_with_ddc(dev, connector,
  _g200_vga_connector_funcs,
- DRM_MODE_CONNECTOR_VGA,
- >adapter);
+ DRM_MODE_CONNECTOR_VGA, ddc);
if (ret) {
drm_err(dev, "drm_connector_init_with_ddc() failed: %d\n", ret);
return ret;
diff --git a/drivers/gpu/drm/mgag200/mgag200_g200eh.c 
b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
index fad62453a91db..619fee7ffdf5e 100644
--- a/drivers/gpu/drm/mgag200/mgag200_g200eh.c
+++ b/drivers/gpu/drm/mgag200/mgag200_g200eh.c
@@ -9,6 +9,7 @@
 #include 
 #include 
 
+#include "mgag200_ddc.h"
 #include "mgag200_drv.h"
 
 void mgag200_g200eh_init_registers(struct mga_device *mdev)
@@ -200,8 +201,8 @@ static int mgag200_g200eh_pipeline_init(struct mga_device 
*mdev)
struct drm_plane *primary_plane = >primary_plane;
struct drm_crtc *crtc = >crtc;
struct drm_encoder *encoder = >encoder;
-   struct mga_i2c_chan *i2c = >i2c;
struct drm_connector *connector = >connector;
+   struct i2c_adapter *ddc;
int ret;
 
ret = drm_universal_plane_init(dev, primary_plane, 0,
@@ -237,16 +238,16 @@ static int mgag200_g200e

[PATCH 06/10] drm/mgag200: Replace struct mga_i2c_chan with struct mgag200_ddc

2024-05-13 Thread Thomas Zimmermann
Rename struct mga_i2c_chan to struct mgag200_ddc, define it in the
source file mgag200_i2c.c, and reorder its fields. Rename all related
variables from i2c to ddc. Also rename the i2c adapter accordingly.

Using the term 'ddc' documents the purpose of the code clearly. The
old term 'i2c' could refer to any functionality on an i2c bus. No
functional changes.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_drv.h | 10 -
 drivers/gpu/drm/mgag200/mgag200_i2c.c | 56 ---
 2 files changed, 33 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h 
b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 3c834bfd82cf4..008fdd5af09c8 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -10,9 +10,6 @@
 #ifndef __MGAG200_DRV_H__
 #define __MGAG200_DRV_H__
 
-#include 
-#include 
-
 #include 
 
 #include 
@@ -189,13 +186,6 @@ static inline struct mgag200_crtc_state 
*to_mgag200_crtc_state(struct drm_crtc_s
return container_of(base, struct mgag200_crtc_state, base);
 }
 
-struct mga_i2c_chan {
-   struct i2c_adapter adapter;
-   struct mga_device *mdev;
-   struct i2c_algo_bit_data bit;
-   int data, clock;
-};
-
 enum mga_type {
G200_PCI,
G200_AGP,
diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c 
b/drivers/gpu/drm/mgag200/mgag200_i2c.c
index ba7aeca55fb40..73ff94c91ca36 100644
--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c
@@ -36,6 +36,16 @@
 #include "mgag200_ddc.h"
 #include "mgag200_drv.h"
 
+struct mgag200_ddc {
+   struct mga_device *mdev;
+
+   int data;
+   int clock;
+
+   struct i2c_algo_bit_data bit;
+   struct i2c_adapter adapter;
+};
+
 static int mga_i2c_read_gpio(struct mga_device *mdev)
 {
WREG8(DAC_INDEX, MGA1064_GEN_IO_DATA);
@@ -63,62 +73,62 @@ static inline void mga_i2c_set(struct mga_device *mdev, int 
mask, int state)
 
 static void mga_gpio_setsda(void *data, int state)
 {
-   struct mga_i2c_chan *i2c = data;
+   struct mgag200_ddc *ddc = data;
 
-   mga_i2c_set(i2c->mdev, i2c->data, state);
+   mga_i2c_set(ddc->mdev, ddc->data, state);
 }
 
 static void mga_gpio_setscl(void *data, int state)
 {
-   struct mga_i2c_chan *i2c = data;
+   struct mgag200_ddc *ddc = data;
 
-   mga_i2c_set(i2c->mdev, i2c->clock, state);
+   mga_i2c_set(ddc->mdev, ddc->clock, state);
 }
 
 static int mga_gpio_getsda(void *data)
 {
-   struct mga_i2c_chan *i2c = data;
+   struct mgag200_ddc *ddc = data;
 
-   return (mga_i2c_read_gpio(i2c->mdev) & i2c->data) ? 1 : 0;
+   return (mga_i2c_read_gpio(ddc->mdev) & ddc->data) ? 1 : 0;
 }
 
 static int mga_gpio_getscl(void *data)
 {
-   struct mga_i2c_chan *i2c = data;
+   struct mgag200_ddc *ddc = data;
 
-   return (mga_i2c_read_gpio(i2c->mdev) & i2c->clock) ? 1 : 0;
+   return (mga_i2c_read_gpio(ddc->mdev) & ddc->clock) ? 1 : 0;
 }
 
-static void mgag200_i2c_release(struct drm_device *dev, void *res)
+static void mgag200_ddc_release(struct drm_device *dev, void *res)
 {
-   struct mga_i2c_chan *i2c = res;
+   struct mgag200_ddc *ddc = res;
 
-   i2c_del_adapter(>adapter);
+   i2c_del_adapter(>adapter);
 }
 
 struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev)
 {
struct drm_device *dev = >base;
const struct mgag200_device_info *info = mdev->info;
-   struct mga_i2c_chan *i2c;
+   struct mgag200_ddc *ddc;
struct i2c_algo_bit_data *bit;
struct i2c_adapter *adapter;
int ret;
 
-   i2c = drmm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
-   if (!i2c)
+   ddc = drmm_kzalloc(dev, sizeof(*ddc), GFP_KERNEL);
+   if (!ddc)
return ERR_PTR(-ENOMEM);
 
WREG_DAC(MGA1064_GEN_IO_CTL2, 1);
WREG_DAC(MGA1064_GEN_IO_DATA, 0xff);
WREG_DAC(MGA1064_GEN_IO_CTL, 0);
 
-   i2c->mdev = mdev;
-   i2c->data = BIT(info->i2c.data_bit);
-   i2c->clock = BIT(info->i2c.clock_bit);
+   ddc->mdev = mdev;
+   ddc->data = BIT(info->i2c.data_bit);
+   ddc->clock = BIT(info->i2c.clock_bit);
 
-   bit = >bit;
-   bit->data = i2c;
+   bit = >bit;
+   bit->data = ddc;
bit->setsda = mga_gpio_setsda;
bit->setscl = mga_gpio_setscl;
bit->getsda = mga_gpio_getsda;
@@ -126,18 +136,18 @@ struct i2c_adapter *mgag200_ddc_create(struct mga_device 
*mdev)
bit->udelay = 10;
bit->timeout = usecs_to_jiffies(2200);
 
-   adapter = >adapter;
+   adapter = >adapter;
adapter->owner = THIS_MODULE;
adapter->algo_data = bit;
adapter->dev.parent = dev->dev;
-   snprintf(adapter->name, sizeof(adapter->name), "mga i2c");
- 

[PATCH 08/10] drm/mgag200: Rename struct i2c_algo_bit_data callbacks

2024-05-13 Thread Thomas Zimmermann
Align the names of the algo-bit helpers with mgag200's convention of
using an mgag200 prefix plus the struct's name plus the callback's name
for such function symbols.

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

diff --git a/drivers/gpu/drm/mgag200/mgag200_ddc.c 
b/drivers/gpu/drm/mgag200/mgag200_ddc.c
index 73ff94c91ca36..3fa11b190943e 100644
--- a/drivers/gpu/drm/mgag200/mgag200_ddc.c
+++ b/drivers/gpu/drm/mgag200/mgag200_ddc.c
@@ -71,28 +71,28 @@ static inline void mga_i2c_set(struct mga_device *mdev, int 
mask, int state)
mga_i2c_set_gpio(mdev, ~mask, state);
 }
 
-static void mga_gpio_setsda(void *data, int state)
+static void mgag200_ddc_algo_bit_data_setsda(void *data, int state)
 {
struct mgag200_ddc *ddc = data;
 
mga_i2c_set(ddc->mdev, ddc->data, state);
 }
 
-static void mga_gpio_setscl(void *data, int state)
+static void mgag200_ddc_algo_bit_data_setscl(void *data, int state)
 {
struct mgag200_ddc *ddc = data;
 
mga_i2c_set(ddc->mdev, ddc->clock, state);
 }
 
-static int mga_gpio_getsda(void *data)
+static int mgag200_ddc_algo_bit_data_getsda(void *data)
 {
struct mgag200_ddc *ddc = data;
 
return (mga_i2c_read_gpio(ddc->mdev) & ddc->data) ? 1 : 0;
 }
 
-static int mga_gpio_getscl(void *data)
+static int mgag200_ddc_algo_bit_data_getscl(void *data)
 {
struct mgag200_ddc *ddc = data;
 
@@ -129,10 +129,10 @@ struct i2c_adapter *mgag200_ddc_create(struct mga_device 
*mdev)
 
bit = >bit;
bit->data = ddc;
-   bit->setsda = mga_gpio_setsda;
-   bit->setscl = mga_gpio_setscl;
-   bit->getsda = mga_gpio_getsda;
-   bit->getscl = mga_gpio_getscl;
+   bit->setsda = mgag200_ddc_algo_bit_data_setsda;
+   bit->setscl = mgag200_ddc_algo_bit_data_setscl;
+   bit->getsda = mgag200_ddc_algo_bit_data_getsda;
+   bit->getscl = mgag200_ddc_algo_bit_data_getscl;
bit->udelay = 10;
bit->timeout = usecs_to_jiffies(2200);
 
-- 
2.45.0



[PATCH 09/10] drm/mgag200: Acquire I/O-register lock in DDC code

2024-05-13 Thread Thomas Zimmermann
The modeset lock protects the DDC code from concurrent modeset
operations, which use the same registers. Move that code from the
connector helpers into the DDC helpers .pre_xfer() and .post_xfer().

Both, .pre_xfer() and .post_xfer(), enclose the transfer of data blocks
over the I2C channel in the internal I2C function bit_xfer(). Both
calls are executed unconditionally if present. Invoking DDC transfers
from any where within the driver now takes the lock.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_ddc.c  | 24 
 drivers/gpu/drm/mgag200/mgag200_mode.c |  9 -
 2 files changed, 24 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_ddc.c 
b/drivers/gpu/drm/mgag200/mgag200_ddc.c
index 3fa11b190943e..6d81ea8931e88 100644
--- a/drivers/gpu/drm/mgag200/mgag200_ddc.c
+++ b/drivers/gpu/drm/mgag200/mgag200_ddc.c
@@ -99,6 +99,28 @@ static int mgag200_ddc_algo_bit_data_getscl(void *data)
return (mga_i2c_read_gpio(ddc->mdev) & ddc->clock) ? 1 : 0;
 }
 
+static int mgag200_ddc_algo_bit_data_pre_xfer(struct i2c_adapter *adapter)
+{
+   struct mgag200_ddc *ddc = i2c_get_adapdata(adapter);
+   struct mga_device *mdev = ddc->mdev;
+
+   /*
+* Protect access to I/O registers from concurrent modesetting
+* by acquiring the I/O-register lock.
+*/
+   mutex_lock(>rmmio_lock);
+
+   return 0;
+}
+
+static void mgag200_ddc_algo_bit_data_post_xfer(struct i2c_adapter *adapter)
+{
+   struct mgag200_ddc *ddc = i2c_get_adapdata(adapter);
+   struct mga_device *mdev = ddc->mdev;
+
+   mutex_unlock(>rmmio_lock);
+}
+
 static void mgag200_ddc_release(struct drm_device *dev, void *res)
 {
struct mgag200_ddc *ddc = res;
@@ -133,6 +155,8 @@ struct i2c_adapter *mgag200_ddc_create(struct mga_device 
*mdev)
bit->setscl = mgag200_ddc_algo_bit_data_setscl;
bit->getsda = mgag200_ddc_algo_bit_data_getsda;
bit->getscl = mgag200_ddc_algo_bit_data_getscl;
+   bit->pre_xfer = mgag200_ddc_algo_bit_data_pre_xfer;
+   bit->post_xfer = mgag200_ddc_algo_bit_data_post_xfer;
bit->udelay = 10;
bit->timeout = usecs_to_jiffies(2200);
 
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c 
b/drivers/gpu/drm/mgag200/mgag200_mode.c
index cd1f48b2f9986..a04c2b550be02 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -743,23 +743,14 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc 
*crtc, struct drm_crtc_st
 
 int mgag200_vga_connector_helper_get_modes(struct drm_connector *connector)
 {
-   struct mga_device *mdev = to_mga_device(connector->dev);
const struct drm_edid *drm_edid;
int count;
 
-   /*
-* Protect access to I/O registers from concurrent modesetting
-* by acquiring the I/O-register lock.
-*/
-   mutex_lock(>rmmio_lock);
-
drm_edid = drm_edid_read(connector);
drm_edid_connector_update(connector, drm_edid);
count = drm_edid_connector_add_modes(connector);
drm_edid_free(drm_edid);
 
-   mutex_unlock(>rmmio_lock);
-
return count;
 }
 
-- 
2.45.0



[PATCH 00/10] drm/mgag200: Refactor DDC code

2024-05-13 Thread Thomas Zimmermann
Clean up a the driver's DDC code, make it simpler, more robust, and
mostly self contained. The patches in this patchset have previously
been sent as part of rev 1 of [1].

Patches 1 and 2 fix long-standing problems in the DDC code.

Patches 3 to 9 refactor the DDC code. The code then keeps its data
structures internal, acquires locks automatically and is much more
readable overall.

Patch 10 replaces driver code with an equivalent helper.

Tested on various Matrox hardware.

[1] https://patchwork.freedesktop.org/series/131977/

Thomas Zimmermann (10):
  drm/mgag200: Set DDC timeout in milliseconds
  drm/mgag200: Bind I2C lifetime to DRM device
  drm/mgag200: Store pointer to struct mga_device in struct mga_i2c_chan
  drm/mgag200: Allocate instance of struct mga_i2c_chan dynamically
  drm/mgag200: Inline mgag200_i2c_init()
  drm/mgag200: Replace struct mga_i2c_chan with struct mgag200_ddc
  drm/mgag200: Rename mgag200_i2c.c to mgag200_ddc.c
  drm/mgag200: Rename struct i2c_algo_bit_data callbacks
  drm/mgag200: Acquire I/O-register lock in DDC code
  drm/mgag200: Use drm_connector_helper_get_modes()

 drivers/gpu/drm/mgag200/Makefile  |   2 +-
 drivers/gpu/drm/mgag200/mgag200_ddc.c | 179 ++
 drivers/gpu/drm/mgag200/mgag200_ddc.h |  11 ++
 drivers/gpu/drm/mgag200/mgag200_drv.h |  18 +--
 drivers/gpu/drm/mgag200/mgag200_g200.c|  11 +-
 drivers/gpu/drm/mgag200/mgag200_g200eh.c  |  11 +-
 drivers/gpu/drm/mgag200/mgag200_g200eh3.c |  11 +-
 drivers/gpu/drm/mgag200/mgag200_g200er.c  |  11 +-
 drivers/gpu/drm/mgag200/mgag200_g200ev.c  |  11 +-
 drivers/gpu/drm/mgag200/mgag200_g200ew3.c |  11 +-
 drivers/gpu/drm/mgag200/mgag200_g200se.c  |  11 +-
 drivers/gpu/drm/mgag200/mgag200_g200wb.c  |  11 +-
 drivers/gpu/drm/mgag200/mgag200_i2c.c | 129 
 drivers/gpu/drm/mgag200/mgag200_mode.c|  27 +---
 14 files changed, 241 insertions(+), 213 deletions(-)
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_ddc.c
 create mode 100644 drivers/gpu/drm/mgag200/mgag200_ddc.h
 delete mode 100644 drivers/gpu/drm/mgag200/mgag200_i2c.c

-- 
2.45.0



[PATCH 02/10] drm/mgag200: Bind I2C lifetime to DRM device

2024-05-13 Thread Thomas Zimmermann
Managed cleanup with devm_add_action_or_reset() will release the I2C
adapter when the underlying Linux device goes away. But the connector
still refers to it, so this cleanup leaves behind a stale pointer
in struct drm_connector.ddc.

Bind the lifetime of the I2C adapter to the connector's lifetime by
using DRM's managed release. When the DRM device goes away (after
the Linux device) DRM will first clean up the connector and then
clean up the I2C adapter.

Signed-off-by: Thomas Zimmermann 
Fixes: b279df242972 ("drm/mgag200: Switch I2C code to managed cleanup")
Cc: Thomas Zimmermann 
Cc: Jocelyn Falempe 
Cc: Dave Airlie 
Cc: dri-devel@lists.freedesktop.org
Cc:  # v6.0+
---
 drivers/gpu/drm/mgag200/mgag200_i2c.c | 6 --
 1 file changed, 4 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c 
b/drivers/gpu/drm/mgag200/mgag200_i2c.c
index 1029fef590f9b..4caeb68f3010c 100644
--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c
@@ -31,6 +31,8 @@
 #include 
 #include 
 
+#include 
+
 #include "mgag200_drv.h"
 
 static int mga_i2c_read_gpio(struct mga_device *mdev)
@@ -86,7 +88,7 @@ static int mga_gpio_getscl(void *data)
return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0;
 }
 
-static void mgag200_i2c_release(void *res)
+static void mgag200_i2c_release(struct drm_device *dev, void *res)
 {
struct mga_i2c_chan *i2c = res;
 
@@ -125,5 +127,5 @@ int mgag200_i2c_init(struct mga_device *mdev, struct 
mga_i2c_chan *i2c)
if (ret)
return ret;
 
-   return devm_add_action_or_reset(dev->dev, mgag200_i2c_release, i2c);
+   return drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c);
 }
-- 
2.45.0



[PATCH 05/10] drm/mgag200: Inline mgag200_i2c_init()

2024-05-13 Thread Thomas Zimmermann
The function mgag200_i2c_init() is an internal helper that sets
up the i2c data structure. Inline its code into the only caller.
Rearrange the individual steps to separate among i2c algorithm,
adapter and fields in struct mga_i2c_chan.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_i2c.c | 62 +--
 1 file changed, 29 insertions(+), 33 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c 
b/drivers/gpu/drm/mgag200/mgag200_i2c.c
index 46fa9f1b4e469..ba7aeca55fb40 100644
--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c
@@ -96,54 +96,50 @@ static void mgag200_i2c_release(struct drm_device *dev, 
void *res)
i2c_del_adapter(>adapter);
 }
 
-static int mgag200_i2c_init(struct mga_device *mdev, struct mga_i2c_chan *i2c)
+struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev)
 {
struct drm_device *dev = >base;
const struct mgag200_device_info *info = mdev->info;
+   struct mga_i2c_chan *i2c;
+   struct i2c_algo_bit_data *bit;
+   struct i2c_adapter *adapter;
int ret;
 
+   i2c = drmm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
+   if (!i2c)
+   return ERR_PTR(-ENOMEM);
+
WREG_DAC(MGA1064_GEN_IO_CTL2, 1);
WREG_DAC(MGA1064_GEN_IO_DATA, 0xff);
WREG_DAC(MGA1064_GEN_IO_CTL, 0);
 
+   i2c->mdev = mdev;
i2c->data = BIT(info->i2c.data_bit);
i2c->clock = BIT(info->i2c.clock_bit);
-   i2c->adapter.owner = THIS_MODULE;
-   i2c->adapter.dev.parent = dev->dev;
-   i2c->mdev = mdev;
-   i2c_set_adapdata(>adapter, i2c);
-   snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "mga i2c");
-
-   i2c->adapter.algo_data = >bit;
 
-   i2c->bit.udelay = 10;
-   i2c->bit.timeout = usecs_to_jiffies(2200);
-   i2c->bit.data = i2c;
-   i2c->bit.setsda = mga_gpio_setsda;
-   i2c->bit.setscl = mga_gpio_setscl;
-   i2c->bit.getsda = mga_gpio_getsda;
-   i2c->bit.getscl = mga_gpio_getscl;
-
-   ret = i2c_bit_add_bus(>adapter);
+   bit = >bit;
+   bit->data = i2c;
+   bit->setsda = mga_gpio_setsda;
+   bit->setscl = mga_gpio_setscl;
+   bit->getsda = mga_gpio_getsda;
+   bit->getscl = mga_gpio_getscl;
+   bit->udelay = 10;
+   bit->timeout = usecs_to_jiffies(2200);
+
+   adapter = >adapter;
+   adapter->owner = THIS_MODULE;
+   adapter->algo_data = bit;
+   adapter->dev.parent = dev->dev;
+   snprintf(adapter->name, sizeof(adapter->name), "mga i2c");
+   i2c_set_adapdata(adapter, i2c);
+
+   ret = i2c_bit_add_bus(adapter);
if (ret)
-   return ret;
-
-   return drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c);
-}
-
-struct i2c_adapter *mgag200_ddc_create(struct mga_device *mdev)
-{
-   struct mga_i2c_chan *i2c;
-   struct drm_device *dev = >base;
-   int ret;
-
-   i2c = drmm_kzalloc(dev, sizeof(*i2c), GFP_KERNEL);
-   if (!i2c)
-   return ERR_PTR(-ENOMEM);
+   return ERR_PTR(ret);
 
-   ret = mgag200_i2c_init(mdev, i2c);
+   ret = drmm_add_action_or_reset(dev, mgag200_i2c_release, i2c);
if (ret)
return ERR_PTR(ret);
 
-   return >adapter;
+   return adapter;
 }
-- 
2.45.0



[PATCH 07/10] drm/mgag200: Rename mgag200_i2c.c to mgag200_ddc.c

2024-05-13 Thread Thomas Zimmermann
Rename the source file according to its content. No functional
changes.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/Makefile | 2 +-
 drivers/gpu/drm/mgag200/{mgag200_i2c.c => mgag200_ddc.c} | 0
 2 files changed, 1 insertion(+), 1 deletion(-)
 rename drivers/gpu/drm/mgag200/{mgag200_i2c.c => mgag200_ddc.c} (100%)

diff --git a/drivers/gpu/drm/mgag200/Makefile b/drivers/gpu/drm/mgag200/Makefile
index 182e224c460dd..0b919352046eb 100644
--- a/drivers/gpu/drm/mgag200/Makefile
+++ b/drivers/gpu/drm/mgag200/Makefile
@@ -1,6 +1,7 @@
 # SPDX-License-Identifier: GPL-2.0-only
 mgag200-y := \
mgag200_bmc.o \
+   mgag200_ddc.o \
mgag200_drv.o \
mgag200_g200.o \
mgag200_g200eh.o \
@@ -10,7 +11,6 @@ mgag200-y := \
mgag200_g200ew3.o \
mgag200_g200se.o \
mgag200_g200wb.o \
-   mgag200_i2c.o \
mgag200_mode.o
 
 obj-$(CONFIG_DRM_MGAG200) += mgag200.o
diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c 
b/drivers/gpu/drm/mgag200/mgag200_ddc.c
similarity index 100%
rename from drivers/gpu/drm/mgag200/mgag200_i2c.c
rename to drivers/gpu/drm/mgag200/mgag200_ddc.c
-- 
2.45.0



[PATCH 01/10] drm/mgag200: Set DDC timeout in milliseconds

2024-05-13 Thread Thomas Zimmermann
Compute the i2c timeout in jiffies from a value in milliseconds. The
original values of 2 jiffies equals 2 milliseconds if HZ has been
configured to a value of 1000. This corresponds to 2.2 milliseconds
used by most other DRM drivers. Update mgag200 accordingly.

Signed-off-by: Thomas Zimmermann 
Fixes: 414c45310625 ("mgag200: initial g200se driver (v2)")
Cc: Dave Airlie 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: Thomas Zimmermann 
Cc: Jocelyn Falempe 
Cc: dri-devel@lists.freedesktop.org
Cc:  # v3.5+
---
 drivers/gpu/drm/mgag200/mgag200_i2c.c | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c 
b/drivers/gpu/drm/mgag200/mgag200_i2c.c
index 423eb302be7eb..1029fef590f9b 100644
--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c
@@ -114,7 +114,7 @@ int mgag200_i2c_init(struct mga_device *mdev, struct 
mga_i2c_chan *i2c)
i2c->adapter.algo_data = >bit;
 
i2c->bit.udelay = 10;
-   i2c->bit.timeout = 2;
+   i2c->bit.timeout = usecs_to_jiffies(2200);
i2c->bit.data = i2c;
i2c->bit.setsda = mga_gpio_setsda;
i2c->bit.setscl = mga_gpio_setscl;
-- 
2.45.0



[PATCH 10/10] drm/mgag200: Use drm_connector_helper_get_modes()

2024-05-13 Thread Thomas Zimmermann
Mgag200's .get_modes() function is identical to the common helper.
Use the latter.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_drv.h  |  4 +---
 drivers/gpu/drm/mgag200/mgag200_mode.c | 17 -
 2 files changed, 1 insertion(+), 20 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h 
b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 008fdd5af09c8..20e3710e056b3 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -420,10 +420,8 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc 
*crtc, struct drm_crtc_st
 #define MGAG200_DAC_ENCODER_FUNCS \
.destroy = drm_encoder_cleanup
 
-int mgag200_vga_connector_helper_get_modes(struct drm_connector *connector);
-
 #define MGAG200_VGA_CONNECTOR_HELPER_FUNCS \
-   .get_modes  = mgag200_vga_connector_helper_get_modes
+   .get_modes = drm_connector_helper_get_modes
 
 #define MGAG200_VGA_CONNECTOR_FUNCS \
.reset  = drm_atomic_helper_connector_reset, \
diff --git a/drivers/gpu/drm/mgag200/mgag200_mode.c 
b/drivers/gpu/drm/mgag200/mgag200_mode.c
index a04c2b550be02..d566e8476bf81 100644
--- a/drivers/gpu/drm/mgag200/mgag200_mode.c
+++ b/drivers/gpu/drm/mgag200/mgag200_mode.c
@@ -737,23 +737,6 @@ void mgag200_crtc_atomic_destroy_state(struct drm_crtc 
*crtc, struct drm_crtc_st
kfree(mgag200_crtc_state);
 }
 
-/*
- * Connector
- */
-
-int mgag200_vga_connector_helper_get_modes(struct drm_connector *connector)
-{
-   const struct drm_edid *drm_edid;
-   int count;
-
-   drm_edid = drm_edid_read(connector);
-   drm_edid_connector_update(connector, drm_edid);
-   count = drm_edid_connector_add_modes(connector);
-   drm_edid_free(drm_edid);
-
-   return count;
-}
-
 /*
  * Mode config
  */
-- 
2.45.0



[PATCH 03/10] drm/mgag200: Store pointer to struct mga_device in struct mga_i2c_chan

2024-05-13 Thread Thomas Zimmermann
Avoid upcasting to struct mga_device in i2c code by storing the
pointer directly. No functional changes.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/mgag200/mgag200_drv.h |  2 +-
 drivers/gpu/drm/mgag200/mgag200_i2c.c | 18 +-
 2 files changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/gpu/drm/mgag200/mgag200_drv.h 
b/drivers/gpu/drm/mgag200/mgag200_drv.h
index 58a0e62eaf183..c7d4047301bfb 100644
--- a/drivers/gpu/drm/mgag200/mgag200_drv.h
+++ b/drivers/gpu/drm/mgag200/mgag200_drv.h
@@ -191,7 +191,7 @@ static inline struct mgag200_crtc_state 
*to_mgag200_crtc_state(struct drm_crtc_s
 
 struct mga_i2c_chan {
struct i2c_adapter adapter;
-   struct drm_device *dev;
+   struct mga_device *mdev;
struct i2c_algo_bit_data bit;
int data, clock;
 };
diff --git a/drivers/gpu/drm/mgag200/mgag200_i2c.c 
b/drivers/gpu/drm/mgag200/mgag200_i2c.c
index 4caeb68f3010c..effd7c057fce0 100644
--- a/drivers/gpu/drm/mgag200/mgag200_i2c.c
+++ b/drivers/gpu/drm/mgag200/mgag200_i2c.c
@@ -63,29 +63,29 @@ static inline void mga_i2c_set(struct mga_device *mdev, int 
mask, int state)
 static void mga_gpio_setsda(void *data, int state)
 {
struct mga_i2c_chan *i2c = data;
-   struct mga_device *mdev = to_mga_device(i2c->dev);
-   mga_i2c_set(mdev, i2c->data, state);
+
+   mga_i2c_set(i2c->mdev, i2c->data, state);
 }
 
 static void mga_gpio_setscl(void *data, int state)
 {
struct mga_i2c_chan *i2c = data;
-   struct mga_device *mdev = to_mga_device(i2c->dev);
-   mga_i2c_set(mdev, i2c->clock, state);
+
+   mga_i2c_set(i2c->mdev, i2c->clock, state);
 }
 
 static int mga_gpio_getsda(void *data)
 {
struct mga_i2c_chan *i2c = data;
-   struct mga_device *mdev = to_mga_device(i2c->dev);
-   return (mga_i2c_read_gpio(mdev) & i2c->data) ? 1 : 0;
+
+   return (mga_i2c_read_gpio(i2c->mdev) & i2c->data) ? 1 : 0;
 }
 
 static int mga_gpio_getscl(void *data)
 {
struct mga_i2c_chan *i2c = data;
-   struct mga_device *mdev = to_mga_device(i2c->dev);
-   return (mga_i2c_read_gpio(mdev) & i2c->clock) ? 1 : 0;
+
+   return (mga_i2c_read_gpio(i2c->mdev) & i2c->clock) ? 1 : 0;
 }
 
 static void mgag200_i2c_release(struct drm_device *dev, void *res)
@@ -109,7 +109,7 @@ int mgag200_i2c_init(struct mga_device *mdev, struct 
mga_i2c_chan *i2c)
i2c->clock = BIT(info->i2c.clock_bit);
i2c->adapter.owner = THIS_MODULE;
i2c->adapter.dev.parent = dev->dev;
-   i2c->dev = dev;
+   i2c->mdev = mdev;
i2c_set_adapdata(>adapter, i2c);
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name), "mga i2c");
 
-- 
2.45.0



[PATCH v3 0/5] drm/udl: Convert to struct drm_edid

2024-05-10 Thread Thomas Zimmermann
Convert udl to use struct drm_edid and its helpers. Also clean up
a few things in the process.

Patch 1 fixes a bug.

Patches 2 to 4 convert the current EDID handling to struct drm_edid
and its helpers. Patch 4 also separates the helpers for .get_modes()
and .detect_ctx() from each other.

Patch 5 removes the obsolete struct udl_connector.

v3:
- implement udl_probe_edid() with memchr_inv() (Jani)
v2:
- drop the generic EDID probing (Jani)
- fixes

Thomas Zimmermann (5):
  drm/udl: Remove DRM_CONNECTOR_POLL_HPD
  drm/udl: Move drm_dev_{enter,exit}() into udl_get_edid_block()
  drm/udl: Clean up Makefile
  drm/udl: Untangle .get_modes() and .detect_ctx()
  drm/udl: Remove struct udl_connector

 drivers/gpu/drm/udl/Makefile  |   8 +-
 drivers/gpu/drm/udl/udl_drv.h |  12 +--
 drivers/gpu/drm/udl/udl_edid.c|  80 +
 drivers/gpu/drm/udl/udl_edid.h|  15 
 drivers/gpu/drm/udl/udl_modeset.c | 138 +++---
 5 files changed, 132 insertions(+), 121 deletions(-)
 create mode 100644 drivers/gpu/drm/udl/udl_edid.c
 create mode 100644 drivers/gpu/drm/udl/udl_edid.h

-- 
2.44.0



[PATCH v3 3/5] drm/udl: Clean up Makefile

2024-05-10 Thread Thomas Zimmermann
Clean up Makefile before listing new object files. No functional
changes.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/udl/Makefile | 7 ++-
 1 file changed, 6 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile
index 3f6db179455d1..00690741db376 100644
--- a/drivers/gpu/drm/udl/Makefile
+++ b/drivers/gpu/drm/udl/Makefile
@@ -1,4 +1,9 @@
 # SPDX-License-Identifier: GPL-2.0-only
-udl-y := udl_drv.o udl_modeset.o udl_main.o udl_transfer.o
+
+udl-y := \
+   udl_drv.o \
+   udl_main.o \
+   udl_modeset.o \
+   udl_transfer.o
 
 obj-$(CONFIG_DRM_UDL) := udl.o
-- 
2.44.0



[PATCH v3 5/5] drm/udl: Remove struct udl_connector

2024-05-10 Thread Thomas Zimmermann
Udl's struct udl_connector is an empty wrapper around struct
drm_connector. Remove it. Allocate the connector as part of struct
udl_device and inline the init function into its only caller.

v2:
- fix return value in udl_modeset_init() (Dan)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/udl/udl_drv.h | 10 +--
 drivers/gpu/drm/udl/udl_modeset.c | 49 +++
 2 files changed, 11 insertions(+), 48 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index f112cfb270f31..1eb716d9dad57 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -49,15 +49,6 @@ struct urb_list {
size_t size;
 };
 
-struct udl_connector {
-   struct drm_connector connector;
-};
-
-static inline struct udl_connector *to_udl_connector(struct drm_connector 
*connector)
-{
-   return container_of(connector, struct udl_connector, connector);
-}
-
 struct udl_device {
struct drm_device drm;
struct device *dev;
@@ -66,6 +57,7 @@ struct udl_device {
struct drm_plane primary_plane;
struct drm_crtc crtc;
struct drm_encoder encoder;
+   struct drm_connector connector;
 
struct mutex gem_lock;
 
diff --git a/drivers/gpu/drm/udl/udl_modeset.c 
b/drivers/gpu/drm/udl/udl_modeset.c
index 4236ce57f5945..bbb04f98886a2 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -444,49 +444,14 @@ static const struct drm_connector_helper_funcs 
udl_connector_helper_funcs = {
.detect_ctx = udl_connector_helper_detect_ctx,
 };
 
-static void udl_connector_destroy(struct drm_connector *connector)
-{
-   struct udl_connector *udl_connector = to_udl_connector(connector);
-
-   drm_connector_cleanup(connector);
-   kfree(udl_connector);
-}
-
 static const struct drm_connector_funcs udl_connector_funcs = {
.reset = drm_atomic_helper_connector_reset,
.fill_modes = drm_helper_probe_single_connector_modes,
-   .destroy = udl_connector_destroy,
+   .destroy = drm_connector_cleanup,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
 };
 
-struct drm_connector *udl_connector_init(struct drm_device *dev)
-{
-   struct udl_connector *udl_connector;
-   struct drm_connector *connector;
-   int ret;
-
-   udl_connector = kzalloc(sizeof(*udl_connector), GFP_KERNEL);
-   if (!udl_connector)
-   return ERR_PTR(-ENOMEM);
-
-   connector = _connector->connector;
-   ret = drm_connector_init(dev, connector, _connector_funcs, 
DRM_MODE_CONNECTOR_VGA);
-   if (ret)
-   goto err_kfree;
-
-   drm_connector_helper_add(connector, _connector_helper_funcs);
-
-   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
-   DRM_CONNECTOR_POLL_DISCONNECT;
-
-   return connector;
-
-err_kfree:
-   kfree(udl_connector);
-   return ERR_PTR(ret);
-}
-
 /*
  * Modesetting
  */
@@ -556,9 +521,15 @@ int udl_modeset_init(struct drm_device *dev)
return ret;
encoder->possible_crtcs = drm_crtc_mask(crtc);
 
-   connector = udl_connector_init(dev);
-   if (IS_ERR(connector))
-   return PTR_ERR(connector);
+   connector = >connector;
+   ret = drm_connector_init(dev, connector, _connector_funcs, 
DRM_MODE_CONNECTOR_VGA);
+   if (ret)
+   return ret;
+   drm_connector_helper_add(connector, _connector_helper_funcs);
+
+   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
+   DRM_CONNECTOR_POLL_DISCONNECT;
+
ret = drm_connector_attach_encoder(connector, encoder);
if (ret)
return ret;
-- 
2.44.0



[PATCH v3 4/5] drm/udl: Untangle .get_modes() and .detect_ctx()

2024-05-10 Thread Thomas Zimmermann
Provide separate implementations of .get_modes() and .detect_ctx()
from struct drm_connector. Switch to struct drm_edid.

Udl's .detect() helper used to fetch the EDID from the adapter and the
.get_modes() helper provided display modes from the data. But this
relied on the DRM helpers to call the functions in the correct order.
When no EDID could be retrieved, .detect() regularly printed a warning
to the kernel log.

Switching to the new helpers around struct drm_edid separates both from
each other. The .get_modes() helper now fetches the EDID by itself and
the .detect_ctx() helper only tests for its presence. The patch does a
number of things to implement this.

- Move udl_get_edid_block() to udl_edid.c and rename it to
udl_read_edid_block(). Then use the helper to implement probing in
udl_probe_edid() and reading in udl_edid_read(). The latter helper
is build on top of DRM helpers.

- Replace the existing code in .get_modes() and .detect() with udl's
new EDID helpers. The new code behaves like DRM's similar DDC-based
helpers. Instead of .detect(), udl now implements .detect_ctx().

- Remove the edid data from struct udl_connector. The field cached
the EDID data between calls to .detect() and .get_modes(), but is now
unused.

v3:
- implement udl_probe_edid() with memchr_inv() (Jani)

v2:
- implement udl_probe_edid() within udl
- reword commit description

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/udl/Makefile  |  1 +
 drivers/gpu/drm/udl/udl_drv.h |  2 -
 drivers/gpu/drm/udl/udl_edid.c| 80 +++
 drivers/gpu/drm/udl/udl_edid.h| 15 ++
 drivers/gpu/drm/udl/udl_modeset.c | 90 +++
 5 files changed, 115 insertions(+), 73 deletions(-)
 create mode 100644 drivers/gpu/drm/udl/udl_edid.c
 create mode 100644 drivers/gpu/drm/udl/udl_edid.h

diff --git a/drivers/gpu/drm/udl/Makefile b/drivers/gpu/drm/udl/Makefile
index 00690741db376..43d69a16af183 100644
--- a/drivers/gpu/drm/udl/Makefile
+++ b/drivers/gpu/drm/udl/Makefile
@@ -2,6 +2,7 @@
 
 udl-y := \
udl_drv.o \
+   udl_edid.o \
udl_main.o \
udl_modeset.o \
udl_transfer.o
diff --git a/drivers/gpu/drm/udl/udl_drv.h b/drivers/gpu/drm/udl/udl_drv.h
index 282ebd6c02fda..f112cfb270f31 100644
--- a/drivers/gpu/drm/udl/udl_drv.h
+++ b/drivers/gpu/drm/udl/udl_drv.h
@@ -51,8 +51,6 @@ struct urb_list {
 
 struct udl_connector {
struct drm_connector connector;
-   /* last udl_detect edid */
-   struct edid *edid;
 };
 
 static inline struct udl_connector *to_udl_connector(struct drm_connector 
*connector)
diff --git a/drivers/gpu/drm/udl/udl_edid.c b/drivers/gpu/drm/udl/udl_edid.c
new file mode 100644
index 0..d67e6bf1f2aec
--- /dev/null
+++ b/drivers/gpu/drm/udl/udl_edid.c
@@ -0,0 +1,80 @@
+// SPDX-License-Identifier: GPL-2.0-only
+
+#include 
+
+#include 
+#include 
+
+#include "udl_drv.h"
+#include "udl_edid.h"
+
+static int udl_read_edid_block(void *data, u8 *buf, unsigned int block, size_t 
len)
+{
+   struct udl_device *udl = data;
+   struct drm_device *dev = >drm;
+   struct usb_device *udev = udl_to_usb_device(udl);
+   u8 *read_buff;
+   int idx, ret;
+   size_t i;
+
+   read_buff = kmalloc(2, GFP_KERNEL);
+   if (!read_buff)
+   return -ENOMEM;
+
+   if (!drm_dev_enter(dev, )) {
+   ret = -ENODEV;
+   goto err_kfree;
+   }
+
+   for (i = 0; i < len; i++) {
+   int bval = (i + block * EDID_LENGTH) << 8;
+
+   ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ 0x02, (0x80 | (0x02 << 5)), bval,
+ 0xA1, read_buff, 2, USB_CTRL_GET_TIMEOUT);
+   if (ret < 0) {
+   drm_err(dev, "Read EDID byte %zu failed err %x\n", i, 
ret);
+   goto err_drm_dev_exit;
+   } else if (ret < 1) {
+   ret = -EIO;
+   drm_err(dev, "Read EDID byte %zu failed\n", i);
+   goto err_drm_dev_exit;
+   }
+
+   buf[i] = read_buff[1];
+   }
+
+   drm_dev_exit(idx);
+   kfree(read_buff);
+
+   return 0;
+
+err_drm_dev_exit:
+   drm_dev_exit(idx);
+err_kfree:
+   kfree(read_buff);
+   return ret;
+}
+
+bool udl_probe_edid(struct udl_device *udl)
+{
+   u8 hdr[8];
+   int ret;
+
+   ret = udl_read_edid_block(udl, hdr, 0, sizeof(hdr));
+   if (ret)
+   return false;
+
+   /*
+* The adapter sends all-zeros if no monitor has been
+* connected. We consider anything else a connection.
+*/
+   return !!memchr_inv(hdr, 0, sizeof(hdr));
+}
+
+const struct drm_edid *udl_edid_read(struct drm_connector *connector)
+{
+   struct udl_device *udl = to_udl(

[PATCH v3 1/5] drm/udl: Remove DRM_CONNECTOR_POLL_HPD

2024-05-10 Thread Thomas Zimmermann
DisplayLink devices do not generate hotplug events. Remove the poll
flag DRM_CONNECTOR_POLL_HPD, as it may not be specified together with
DRM_CONNECTOR_POLL_CONNECT or DRM_CONNECTOR_POLL_DISCONNECT.

Signed-off-by: Thomas Zimmermann 
Fixes: afdfc4c6f55f ("drm/udl: Fixed problem with UDL adpater reconnection")
Reviewed-by: Jani Nikula 
Cc: Robert Tarasov 
Cc: Alex Deucher 
Cc: Dave Airlie 
Cc: Sean Paul 
Cc: Thomas Zimmermann 
Cc: dri-devel@lists.freedesktop.org
Cc:  # v4.15+
---
 drivers/gpu/drm/udl/udl_modeset.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_modeset.c 
b/drivers/gpu/drm/udl/udl_modeset.c
index 7702359c90c22..751da3a294c44 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -527,8 +527,7 @@ struct drm_connector *udl_connector_init(struct drm_device 
*dev)
 
drm_connector_helper_add(connector, _connector_helper_funcs);
 
-   connector->polled = DRM_CONNECTOR_POLL_HPD |
-   DRM_CONNECTOR_POLL_CONNECT |
+   connector->polled = DRM_CONNECTOR_POLL_CONNECT |
DRM_CONNECTOR_POLL_DISCONNECT;
 
return connector;
-- 
2.44.0



[PATCH v3 2/5] drm/udl: Move drm_dev_{enter, exit}() into udl_get_edid_block()

2024-05-10 Thread Thomas Zimmermann
Protect the code in udl_get_edid_block() with drm_dev_enter() and
drm_dev_exit(), so that all callers automatically invoke it. The
function uses hardware resources, which can be hot-unplugged at
any time. The other code in udl_connector_detect() does not use the
resources of the hardware device and therefore does not require
protection.

This change will allow to use udl_get_edid_block() in various
contexts easily.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Jani Nikula 
---
 drivers/gpu/drm/udl/udl_modeset.c | 20 +++-
 1 file changed, 11 insertions(+), 9 deletions(-)

diff --git a/drivers/gpu/drm/udl/udl_modeset.c 
b/drivers/gpu/drm/udl/udl_modeset.c
index 751da3a294c44..3df9fc38388b4 100644
--- a/drivers/gpu/drm/udl/udl_modeset.c
+++ b/drivers/gpu/drm/udl/udl_modeset.c
@@ -434,13 +434,18 @@ static int udl_get_edid_block(void *data, u8 *buf, 
unsigned int block, size_t le
struct drm_device *dev = >drm;
struct usb_device *udev = udl_to_usb_device(udl);
u8 *read_buff;
-   int ret;
+   int idx, ret;
size_t i;
 
read_buff = kmalloc(2, GFP_KERNEL);
if (!read_buff)
return -ENOMEM;
 
+   if (!drm_dev_enter(dev, )) {
+   ret = -ENODEV;
+   goto err_kfree;
+   }
+
for (i = 0; i < len; i++) {
int bval = (i + block * EDID_LENGTH) << 8;
 
@@ -449,20 +454,23 @@ static int udl_get_edid_block(void *data, u8 *buf, 
unsigned int block, size_t le
  0xA1, read_buff, 2, USB_CTRL_GET_TIMEOUT);
if (ret < 0) {
drm_err(dev, "Read EDID byte %zu failed err %x\n", i, 
ret);
-   goto err_kfree;
+   goto err_drm_dev_exit;
} else if (ret < 1) {
ret = -EIO;
drm_err(dev, "Read EDID byte %zu failed\n", i);
-   goto err_kfree;
+   goto err_drm_dev_exit;
}
 
buf[i] = read_buff[1];
}
 
+   drm_dev_exit(idx);
kfree(read_buff);
 
return 0;
 
+err_drm_dev_exit:
+   drm_dev_exit(idx);
 err_kfree:
kfree(read_buff);
return ret;
@@ -474,21 +482,15 @@ static enum drm_connector_status 
udl_connector_detect(struct drm_connector *conn
struct udl_device *udl = to_udl(dev);
struct udl_connector *udl_connector = to_udl_connector(connector);
enum drm_connector_status status = connector_status_disconnected;
-   int idx;
 
/* cleanup previous EDID */
kfree(udl_connector->edid);
udl_connector->edid = NULL;
 
-   if (!drm_dev_enter(dev, ))
-   return connector_status_disconnected;
-
udl_connector->edid = drm_do_get_edid(connector, udl_get_edid_block, 
udl);
if (udl_connector->edid)
status = connector_status_connected;
 
-   drm_dev_exit(idx);
-
return status;
 }
 
-- 
2.44.0



Re: [PATCH v2 4/5] drm/udl: Untangle .get_modes() and .detect_ctx()

2024-05-10 Thread Thomas Zimmermann
 udl_connector_helper_funcs = {
+   .get_modes = udl_connector_helper_get_modes,
+   .detect_ctx = udl_connector_helper_detect_ctx,
+};
  
  static void udl_connector_destroy(struct drm_connector *connector)

  {
struct udl_connector *udl_connector = to_udl_connector(connector);
  
  	drm_connector_cleanup(connector);

-   kfree(udl_connector->edid);
kfree(udl_connector);
  }
  
  static const struct drm_connector_funcs udl_connector_funcs = {

.reset = drm_atomic_helper_connector_reset,
-   .detect = udl_connector_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.destroy = udl_connector_destroy,
.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,


--
--
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: simpledrm, running display servers, and drivers replacing simpledrm while the display server is running

2024-05-10 Thread Thomas Zimmermann

Hi


(This was discussed on #dri-devel, but I'll reiterate here as well).

There are two problems at hand; one is the race condition during boot
when the login screen (or whatever display server appears first) is
launched with simpledrm, only some moments later having the real GPU
driver appear.

The other is general purpose GPU hotplugging, including the unplugging
the GPU decided by the compositor to be the primary one.


The situation of booting with simpledrm (problem 2) is a special case of 
problem 1. From the kernel's perspective, unloading simpledrm is the 
same as what you call general purpose GPU hotplugging. Even through 
there is not a full GPU, but a trivial scanout buffer. In userspace, you 
see the same sequence of events as in the general case.




The latter is something that should be handled in userspace, by
compositors, etc, I agree.

The former, however, is not properly solved by userspace learning how to
deal with primary GPU unplugging and switching to using a real GPU
driver, as it'd break the booting and login experience.

When it works, i.e. the race condition is not hit, is this:

  * System boots
  * Plymouth shows a "splash" screen
  * The login screen display server is launched with the real GPU driver
  * The login screen interface is smoothly animating using hardware
accelerating, presenting "advanced" graphical content depending on
hardware capabilities (e.g. high color bit depth, HDR, and so on)

If the race condition is hit, with a compositor supporting primary GPU
hotplugging, it'll work like this:

  * System boots
  * Plymouth shows a "splash" screen
  * The login screen display server is launched with simpledrm
  * Due to using simpldrm, the login screen interface is not animated and
just plops up, and no "advanced" graphical content is enabled due to
apparent missing hardware capabilities
  * The real GPU driver appears, the login screen now starts to become
animated, and may suddenly change appearance due to capabilties
having changed

Thus, by just supporting hotplugging the primary GPU in userspace, we'll
still end up with a glitchy boot experience, and it forces userspace to
add things like sleep(10) to work around this.

In other words, fixing userspace is *not* a correct solution to the
problem, it's a work around (albeit a behaivor we want for other
reasons) for the race condition.


To really fix the flickering, you need to read the old DRM device's 
atomic state and apply it to the new device. Then tell the desktop and 
applications to re-init their rendering stack.


Depending on the DRM driver and its hardware, it might be possible to do 
this without flickering. The key is to not loose the original scanout 
buffer, while not probing the new device driver. But that needs work in 
each individual DRM driver.




Arguably, the only place a more educated guess about whether to wait or
not, and if so how long, is the kernel.


As I said before, driver modules come and go and hardware devices come 
and go.


To detect if there might be a native driver waiting to be loaded, you 
can test for


- 'nomodeset' on the command line -> no native driver
- 'systemd-load-modules' not started -> maybe wait
- look for drivers under /lib/modules//kernel/drivers/gpu/drm/ 
-> maybe wait

- maybe udev can tell you more
- it might for detection help that recently simpledrm devices refer to 
their parent PCI device

- maybe systemd tracks the probed devices

Best regards
Thomas




Jonas


The next best solution is to keep the final DRM device open until a new one
shows up. All DRM graphics drivers with hotplugging support are required to
accept commands after their hardware has been unplugged. They simply won't
display anything.

Best regards
Thomas



Thanks


--
--
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: simpledrm, running display servers, and drivers replacing simpledrm while the display server is running

2024-05-10 Thread Thomas Zimmermann

Hi

Am 09.05.24 um 15:06 schrieb nerdopolis:


Hi


So I have been made aware of an apparent race condition of some 
drivers taking a bit longer to load, which could lead to a possible 
race condition of display servers/greeters using the simpledrm device, 
and then experiencing problems once the real driver loads, the 
simpledrm device that the display servers are using as their primary 
GPU goes away.



For example Weston crashes, Xorg crashes, wlroots seems to stay 
running, but doesn't draw anything on the screen, kwin aborts,


This is if you boot on a QEMU machine with the virtio card, with 
modprobe.blacklist=virtio_gpu, and then, when the display server is 
running, run sudo modprobe virtio-gpu



Namely, it's been recently reported here: 
https://github.com/sddm/sddm/issues/1917 and here 
https://github.com/systemd/systemd/issues/32509



My thinking: Instead of simpledrm's /dev/dri/card0 device going away 
when the real driver loads, is it possible for simpledrm to instead 
simulate an unplug of the fake display/CRTC?




To my knowledge, there's no hotplugging for CRTCs.

That way in theory, the simpledrm device will now be useless for 
drawing for drawing to the screen at that point, since the real driver 
is now taken over, but this way here, at least the display server 
doesn't lose its handles to the /dev/dri/card0 device, (and then maybe 
only remove itself once the final handle to it closes?)



Is something like this possible to do with the way simpledrm works 
with the low level video memory? Or is this not possible?




Userspace needs to be prepared that graphics devices can do hotplugging. 
The correct solution is to make compositors work without graphics devices.


The next best solution is to keep the final DRM device open until a new 
one shows up. All DRM graphics drivers with hotplugging support are 
required to accept commands after their hardware has been unplugged. 
They simply won't display anything.


Best regards
Thomas




Thanks



--
--
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)



[PULL] drm-misc-fixes

2024-05-10 Thread Thomas Zimmermann
Hi Dave, Sima,

this is the weekly drm-misc-fixes PR. Sorry for being late.

Best regards
Thomas

drm-misc-fixes-2024-05-10:
Short summary of fixes pull:

core:
- fix connector debugging output

meson:
- dw-hdmi: power-up fixes
- dw-hdmi: add badngap setting for g12
The following changes since commit da85f0aaa9f21999753b01d45c0343f885a8f905:

  drm/panel: ili9341: Use predefined error codes (2024-05-02 09:41:27 +0200)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/misc/kernel.git 
tags/drm-misc-fixes-2024-05-10

for you to fetch changes up to 6897204ea3df808d342c8e4613135728bc538bcd:

  drm/connector: Add \n to message about demoting connector force-probes 
(2024-05-07 09:17:07 -0700)


Short summary of fixes pull:

core:
- fix connector debugging output

meson:
- dw-hdmi: power-up fixes
- dw-hdmi: add badngap setting for g12


Douglas Anderson (1):
  drm/connector: Add \n to message about demoting connector force-probes

Jerome Brunet (2):
  drm/meson: dw-hdmi: power up phy on device init
  drm/meson: dw-hdmi: add bandgap setting for g12

 drivers/gpu/drm/drm_connector.c   |  2 +-
 drivers/gpu/drm/meson/meson_dw_hdmi.c | 70 ---
 2 files changed, 32 insertions(+), 40 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)


Re: [PATCH 11/11] drm/tegra: Use fbdev client helpers

2024-05-08 Thread Thomas Zimmermann

Hi

Am 07.05.24 um 23:03 schrieb Felix Kuehling:


On 2024-05-07 07:58, Thomas Zimmermann wrote:

Implement struct drm_client_funcs with the respective helpers and
remove the custom code from the emulation. The generic helpers are
equivalent in functionality.

Signed-off-by: Thomas Zimmermann 
---
  drivers/gpu/drm/radeon/radeon_fbdev.c | 66 ++-


Was radeon meant to be a separate patch?


Indeed. It also _was_ a separate patch. This looks like a mistake during 
rebasing. Thanks for noticing. I'll fix that in v2.


Best regards
Thomas



Regards,
  Felix



  drivers/gpu/drm/tegra/fbdev.c | 58 ++-
  2 files changed, 6 insertions(+), 118 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c 
b/drivers/gpu/drm/radeon/radeon_fbdev.c

index 02bf25759059a..cf790922174ea 100644
--- a/drivers/gpu/drm/radeon/radeon_fbdev.c
+++ b/drivers/gpu/drm/radeon/radeon_fbdev.c
@@ -29,7 +29,6 @@
  #include 
  #include 
  -#include 
  #include 
  #include 
  #include 
@@ -293,71 +292,12 @@ static const struct drm_fb_helper_funcs 
radeon_fbdev_fb_helper_funcs = {

  };
    /*
- * Fbdev client and struct drm_client_funcs
+ * struct drm_client_funcs
   */
  -static void radeon_fbdev_client_unregister(struct drm_client_dev 
*client)

-{
-    struct drm_fb_helper *fb_helper = 
drm_fb_helper_from_client(client);

-    struct drm_device *dev = fb_helper->dev;
-    struct radeon_device *rdev = dev->dev_private;
-
-    if (fb_helper->info) {
-    vga_switcheroo_client_fb_set(rdev->pdev, NULL);
-    drm_helper_force_disable_all(dev);
-    drm_fb_helper_unregister_info(fb_helper);
-    } else {
-    drm_client_release(_helper->client);
-    drm_fb_helper_unprepare(fb_helper);
-    kfree(fb_helper);
-    }
-}
-
-static int radeon_fbdev_client_restore(struct drm_client_dev *client)
-{
-    drm_fb_helper_lastclose(client->dev);
-    vga_switcheroo_process_delayed_switch();
-
-    return 0;
-}
-
-static int radeon_fbdev_client_hotplug(struct drm_client_dev *client)
-{
-    struct drm_fb_helper *fb_helper = 
drm_fb_helper_from_client(client);

-    struct drm_device *dev = client->dev;
-    struct radeon_device *rdev = dev->dev_private;
-    int ret;
-
-    if (dev->fb_helper)
-    return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-    ret = drm_fb_helper_init(dev, fb_helper);
-    if (ret)
-    goto err_drm_err;
-
-    if (!drm_drv_uses_atomic_modeset(dev))
-    drm_helper_disable_unused_functions(dev);
-
-    ret = drm_fb_helper_initial_config(fb_helper);
-    if (ret)
-    goto err_drm_fb_helper_fini;
-
-    vga_switcheroo_client_fb_set(rdev->pdev, fb_helper->info);
-
-    return 0;
-
-err_drm_fb_helper_fini:
-    drm_fb_helper_fini(fb_helper);
-err_drm_err:
-    drm_err(dev, "Failed to setup radeon fbdev emulation 
(ret=%d)\n", ret);

-    return ret;
-}
-
  static const struct drm_client_funcs radeon_fbdev_client_funcs = {
-    .owner    = THIS_MODULE,
-    .unregister    = radeon_fbdev_client_unregister,
-    .restore    = radeon_fbdev_client_restore,
-    .hotplug    = radeon_fbdev_client_hotplug,
+    .owner = THIS_MODULE,
+    DRM_FBDEV_HELPER_CLIENT_FUNCS,
  };
    void radeon_fbdev_setup(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/tegra/fbdev.c 
b/drivers/gpu/drm/tegra/fbdev.c

index db6eaac3d30e6..f9cc365cfed94 100644
--- a/drivers/gpu/drm/tegra/fbdev.c
+++ b/drivers/gpu/drm/tegra/fbdev.c
@@ -12,7 +12,6 @@
  #include 
    #include 
-#include 
  #include 
  #include 
  #include 
@@ -150,63 +149,12 @@ static const struct drm_fb_helper_funcs 
tegra_fb_helper_funcs = {

  };
    /*
- * struct drm_client
+ * struct drm_client_funcs
   */
  -static void tegra_fbdev_client_unregister(struct drm_client_dev 
*client)

-{
-    struct drm_fb_helper *fb_helper = 
drm_fb_helper_from_client(client);

-
-    if (fb_helper->info) {
-    drm_fb_helper_unregister_info(fb_helper);
-    } else {
-    drm_client_release(_helper->client);
-    drm_fb_helper_unprepare(fb_helper);
-    kfree(fb_helper);
-    }
-}
-
-static int tegra_fbdev_client_restore(struct drm_client_dev *client)
-{
-    drm_fb_helper_lastclose(client->dev);
-
-    return 0;
-}
-
-static int tegra_fbdev_client_hotplug(struct drm_client_dev *client)
-{
-    struct drm_fb_helper *fb_helper = 
drm_fb_helper_from_client(client);

-    struct drm_device *dev = client->dev;
-    int ret;
-
-    if (dev->fb_helper)
-    return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-    ret = drm_fb_helper_init(dev, fb_helper);
-    if (ret)
-    goto err_drm_err;
-
-    if (!drm_drv_uses_atomic_modeset(dev))
-    drm_helper_disable_unused_functions(dev);
-
-    ret = drm_fb_helper_initial_config(fb_helper);
-    if (ret)
-    goto err_drm_fb_helper_fini;
-
-    return 0;
-
-err_drm_fb_helper_fini:
-    drm_fb_helper_fini(fb_helper);
-err_drm_err:
-    drm_err(dev, &qu

Re: [PATCH 00/15] drm: struct drm_edid conversions

2024-05-07 Thread Thomas Zimmermann

Hi

Am 16.04.24 um 15:22 schrieb Jani Nikula:

I've these laying in a branch for a while, maybe let's try to make some
forward progress in this front.


Could you take another look at the udl patches at [1]? The second 
iteration of the patches is self-contained within the driver. So the 
most-controversial points should be resolved now.


Best regards
Thomas

[1] https://patchwork.freedesktop.org/series/132039/#rev2



Build tested only, on x86, arm, and arm64.

BR,
Jani.


Jani Nikula (15):
   drm/panel: simple: switch to struct drm_edid
   drm/panel-samsung-atna33xc20: switch to struct drm_edid
   drm/panel-edp: switch to struct drm_edid
   drm/bridge/analogix/anx6345: switch to struct drm_edid
   drm/bridge/analogix/anx78xx: switch to struct drm_edid
   drm/sun4i: hdmi: switch to struct drm_edid
   drm/vc4: hdmi: switch to struct drm_edid
   drm/bridge: anx7625: use struct drm_edid more
   drm/gud: switch to struct drm_edid
   drm/i2c: tda998x: switch to struct drm_edid
   drm/bochs: switch to struct drm_edid
   drm/virtio: switch to struct drm_edid
   drm/rockchip: cdn-dp: switch to struct drm_edid
   drm/rockchip: inno_hdmi: switch to struct drm_edid
   drm/rockchip: rk3066_hdmi: switch to struct drm_edid

  .../drm/bridge/analogix/analogix-anx6345.c| 15 +++---
  .../drm/bridge/analogix/analogix-anx78xx.c| 23 +-
  drivers/gpu/drm/bridge/analogix/anx7625.c | 26 +++
  drivers/gpu/drm/bridge/analogix/anx7625.h | 10 +---
  drivers/gpu/drm/gud/gud_connector.c   | 12 ++---
  drivers/gpu/drm/i2c/tda998x_drv.c | 19 
  drivers/gpu/drm/panel/panel-edp.c | 17 ---
  .../gpu/drm/panel/panel-samsung-atna33xc20.c  | 13 --
  drivers/gpu/drm/panel/panel-simple.c  | 15 +++---
  drivers/gpu/drm/rockchip/cdn-dp-core.c| 33 +++--
  drivers/gpu/drm/rockchip/cdn-dp-core.h|  2 +-
  drivers/gpu/drm/rockchip/inno_hdmi.c  | 12 ++---
  drivers/gpu/drm/rockchip/rk3066_hdmi.c| 12 ++---
  drivers/gpu/drm/sun4i/sun4i_hdmi_enc.c| 18 +---
  drivers/gpu/drm/tiny/bochs.c  | 23 --
  drivers/gpu/drm/vc4/vc4_hdmi.c| 46 ++-
  drivers/gpu/drm/virtio/virtgpu_display.c  | 10 ++--
  drivers/gpu/drm/virtio/virtgpu_drv.h  |  2 +-
  drivers/gpu/drm/virtio/virtgpu_vq.c   | 12 ++---
  19 files changed, 167 insertions(+), 153 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)



[PATCH] drm/fbdev-shmem: Clean up deferred I/O

2024-05-07 Thread Thomas Zimmermann
Call fb_deferred_io_cleanup() upon destroying the framebuffer
device. Releases the internal memory.

Signed-off-by: Thomas Zimmermann 
Fixes: 150f431a0831 ("drm/fbdev: Add fbdev-shmem")
Cc: Thomas Zimmermann 
Cc: Javier Martinez Canillas 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc: David Airlie 
Cc: Daniel Vetter 
Cc: dri-devel@lists.freedesktop.org
---
 drivers/gpu/drm/drm_fbdev_shmem.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/drm_fbdev_shmem.c 
b/drivers/gpu/drm/drm_fbdev_shmem.c
index a85a8a8e2eb8b..0c785007f11b1 100644
--- a/drivers/gpu/drm/drm_fbdev_shmem.c
+++ b/drivers/gpu/drm/drm_fbdev_shmem.c
@@ -60,6 +60,7 @@ static void drm_fbdev_shmem_fb_destroy(struct fb_info *info)
if (!fb_helper->dev)
return;
 
+   fb_deferred_io_cleanup(info);
drm_fb_helper_fini(fb_helper);
 
drm_client_buffer_vunmap(fb_helper->buffer);
-- 
2.44.0



[PATCH] drm/fbdev-dma: Clean up deferred I/O

2024-05-07 Thread Thomas Zimmermann
Call fb_deferred_io_cleanup() upon destroying the framebuffer
device. Releases the internal memory.

Signed-off-by: Thomas Zimmermann 
Fixes: 808a40b69468 ("drm/fbdev-dma: Implement damage handling and deferred 
I/O")
Cc: Thomas Zimmermann 
Cc: Javier Martinez Canillas 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
---
 drivers/gpu/drm/drm_fbdev_dma.c | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c
index 5eeb5164e9e2b..97ef6300d47e0 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -59,6 +59,7 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info)
if (!fb_helper->dev)
return;
 
+   fb_deferred_io_cleanup(info);
drm_fb_helper_fini(fb_helper);
 
drm_client_buffer_vunmap(fb_helper->buffer);
-- 
2.44.0



Re: [PATCH 08/11] drm/i915: Use drm_fbdev_helper_client_unregister()

2024-05-07 Thread Thomas Zimmermann

Hi

Am 07.05.24 um 14:25 schrieb Rodrigo Vivi:

On Tue, May 07, 2024 at 01:58:29PM +0200, Thomas Zimmermann wrote:

Implement struct drm_client_funcs.unregister with the helpers
drm_fbdev_helper_client_unregister() and remove the custom code
from the driver. The generic helper is equivalent in functionality.

Signed-off-by: Thomas Zimmermann 
---
  drivers/gpu/drm/i915/display/intel_fbdev.c | 21 ++---
  1 file changed, 2 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index bda702c2cab8e..f1b4543bffc02 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -38,7 +38,6 @@
  #include 
  
  #include 

-#include 
  #include 
  #include 
  #include 
@@ -580,25 +579,9 @@ static int intel_fbdev_restore_mode(struct 
drm_i915_private *dev_priv)
  }
  
  /*

- * Fbdev client and struct drm_client_funcs
+ * struct drm_client_funcs
   */
  
-static void intel_fbdev_client_unregister(struct drm_client_dev *client)

-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = fb_helper->dev;
-   struct pci_dev *pdev = to_pci_dev(dev->dev);
-
-   if (fb_helper->info) {
-   vga_switcheroo_client_fb_set(pdev, NULL);
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_fb_helper_unprepare(fb_helper);
-   drm_client_release(_helper->client);

The only real difference is that these 2 calls are inverted in the new
drm_fbdev_helper_client_unregister.


The condition in this if statement is different for some drivers, but 
not i915. The setup code first does a _prepare and then an 
_init+_register, hence the _release goes first and then comes the 
_unprepare.




I feel that the releasing after the unprepare sounds more logical,
but if there's no actual issue with that and it is working for
everybody, let's do that.


It should make no difference in practice, but doing the release first is 
the inverse of the setup; hence conceptually cleaner.




Reviewed-by: Rodrigo Vivi 

Acked-by: Rodrigo Vivi 
(to get through drm-misc with everything else if you prefer)


Thanks.

Best regards
Thomas




-   kfree(fb_helper);
-   }
-}
-
  static int intel_fbdev_client_restore(struct drm_client_dev *client)
  {
struct drm_i915_private *dev_priv = to_i915(client->dev);
@@ -644,7 +627,7 @@ static int intel_fbdev_client_hotplug(struct drm_client_dev 
*client)
  
  static const struct drm_client_funcs intel_fbdev_client_funcs = {

.owner  = THIS_MODULE,
-   .unregister = intel_fbdev_client_unregister,
+   .unregister = drm_fbdev_helper_client_unregister,
.restore= intel_fbdev_client_restore,
.hotplug= intel_fbdev_client_hotplug,
  };
--
2.44.0



--
--
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)



[PATCH 11/11] drm/tegra: Use fbdev client helpers

2024-05-07 Thread Thomas Zimmermann
Implement struct drm_client_funcs with the respective helpers and
remove the custom code from the emulation. The generic helpers are
equivalent in functionality.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/radeon/radeon_fbdev.c | 66 ++-
 drivers/gpu/drm/tegra/fbdev.c | 58 ++-
 2 files changed, 6 insertions(+), 118 deletions(-)

diff --git a/drivers/gpu/drm/radeon/radeon_fbdev.c 
b/drivers/gpu/drm/radeon/radeon_fbdev.c
index 02bf25759059a..cf790922174ea 100644
--- a/drivers/gpu/drm/radeon/radeon_fbdev.c
+++ b/drivers/gpu/drm/radeon/radeon_fbdev.c
@@ -29,7 +29,6 @@
 #include 
 #include 
 
-#include 
 #include 
 #include 
 #include 
@@ -293,71 +292,12 @@ static const struct drm_fb_helper_funcs 
radeon_fbdev_fb_helper_funcs = {
 };
 
 /*
- * Fbdev client and struct drm_client_funcs
+ * struct drm_client_funcs
  */
 
-static void radeon_fbdev_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = fb_helper->dev;
-   struct radeon_device *rdev = dev->dev_private;
-
-   if (fb_helper->info) {
-   vga_switcheroo_client_fb_set(rdev->pdev, NULL);
-   drm_helper_force_disable_all(dev);
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_client_release(_helper->client);
-   drm_fb_helper_unprepare(fb_helper);
-   kfree(fb_helper);
-   }
-}
-
-static int radeon_fbdev_client_restore(struct drm_client_dev *client)
-{
-   drm_fb_helper_lastclose(client->dev);
-   vga_switcheroo_process_delayed_switch();
-
-   return 0;
-}
-
-static int radeon_fbdev_client_hotplug(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = client->dev;
-   struct radeon_device *rdev = dev->dev_private;
-   int ret;
-
-   if (dev->fb_helper)
-   return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-   ret = drm_fb_helper_init(dev, fb_helper);
-   if (ret)
-   goto err_drm_err;
-
-   if (!drm_drv_uses_atomic_modeset(dev))
-   drm_helper_disable_unused_functions(dev);
-
-   ret = drm_fb_helper_initial_config(fb_helper);
-   if (ret)
-   goto err_drm_fb_helper_fini;
-
-   vga_switcheroo_client_fb_set(rdev->pdev, fb_helper->info);
-
-   return 0;
-
-err_drm_fb_helper_fini:
-   drm_fb_helper_fini(fb_helper);
-err_drm_err:
-   drm_err(dev, "Failed to setup radeon fbdev emulation (ret=%d)\n", ret);
-   return ret;
-}
-
 static const struct drm_client_funcs radeon_fbdev_client_funcs = {
-   .owner  = THIS_MODULE,
-   .unregister = radeon_fbdev_client_unregister,
-   .restore= radeon_fbdev_client_restore,
-   .hotplug= radeon_fbdev_client_hotplug,
+   .owner = THIS_MODULE,
+   DRM_FBDEV_HELPER_CLIENT_FUNCS,
 };
 
 void radeon_fbdev_setup(struct radeon_device *rdev)
diff --git a/drivers/gpu/drm/tegra/fbdev.c b/drivers/gpu/drm/tegra/fbdev.c
index db6eaac3d30e6..f9cc365cfed94 100644
--- a/drivers/gpu/drm/tegra/fbdev.c
+++ b/drivers/gpu/drm/tegra/fbdev.c
@@ -12,7 +12,6 @@
 #include 
 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -150,63 +149,12 @@ static const struct drm_fb_helper_funcs 
tegra_fb_helper_funcs = {
 };
 
 /*
- * struct drm_client
+ * struct drm_client_funcs
  */
 
-static void tegra_fbdev_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-
-   if (fb_helper->info) {
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_client_release(_helper->client);
-   drm_fb_helper_unprepare(fb_helper);
-   kfree(fb_helper);
-   }
-}
-
-static int tegra_fbdev_client_restore(struct drm_client_dev *client)
-{
-   drm_fb_helper_lastclose(client->dev);
-
-   return 0;
-}
-
-static int tegra_fbdev_client_hotplug(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = client->dev;
-   int ret;
-
-   if (dev->fb_helper)
-   return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-   ret = drm_fb_helper_init(dev, fb_helper);
-   if (ret)
-   goto err_drm_err;
-
-   if (!drm_drv_uses_atomic_modeset(dev))
-   drm_helper_disable_unused_functions(dev);
-
-   ret = drm_fb_helper_initial_config(fb_helper);
-   if (ret)
-   goto err_drm_fb_helper_fini;
-
-   return 0;
-
-err_drm_fb_helper_fini:
-   drm_fb_helper_fini(fb_helper);
-err_drm_err:
-   drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret);
-   retur

[PATCH 10/11] drm/omapdrm: Use fbdev client helpers

2024-05-07 Thread Thomas Zimmermann
Implement struct drm_client_funcs with the respective helpers and
remove the custom code from the emulation. The generic helpers are
equivalent in functionality.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/omapdrm/omap_fbdev.c | 55 ++--
 1 file changed, 3 insertions(+), 52 deletions(-)

diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c 
b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index 523be34682caf..f6c131932a756 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -7,7 +7,6 @@
 #include 
 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -280,60 +279,12 @@ static struct drm_fb_helper *get_fb(struct fb_info *fbi)
 }
 
 /*
- * struct drm_client
+ * struct drm_client_funcs
  */
 
-static void omap_fbdev_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-
-   if (fb_helper->info) {
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_client_release(_helper->client);
-   drm_fb_helper_unprepare(fb_helper);
-   kfree(fb_helper);
-   }
-}
-
-static int omap_fbdev_client_restore(struct drm_client_dev *client)
-{
-   drm_fb_helper_lastclose(client->dev);
-
-   return 0;
-}
-
-static int omap_fbdev_client_hotplug(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = client->dev;
-   int ret;
-
-   if (dev->fb_helper)
-   return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-   ret = drm_fb_helper_init(dev, fb_helper);
-   if (ret)
-   goto err_drm_err;
-
-   ret = drm_fb_helper_initial_config(fb_helper);
-   if (ret)
-   goto err_drm_fb_helper_fini;
-
-   return 0;
-
-err_drm_fb_helper_fini:
-   drm_fb_helper_fini(fb_helper);
-err_drm_err:
-   drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret);
-   return ret;
-}
-
 static const struct drm_client_funcs omap_fbdev_client_funcs = {
-   .owner  = THIS_MODULE,
-   .unregister = omap_fbdev_client_unregister,
-   .restore= omap_fbdev_client_restore,
-   .hotplug= omap_fbdev_client_hotplug,
+   .owner = THIS_MODULE,
+   DRM_FBDEV_HELPER_CLIENT_FUNCS,
 };
 
 void omap_fbdev_setup(struct drm_device *dev)
-- 
2.44.0



[PATCH 09/11] drm/msm: Use fbdev client helpers

2024-05-07 Thread Thomas Zimmermann
Implement struct drm_client_funcs with the respective helpers and
remove the custom code from the emulation. The generic helpers are
equivalent in functionality.

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

diff --git a/drivers/gpu/drm/msm/msm_fbdev.c b/drivers/gpu/drm/msm/msm_fbdev.c
index 030bedac632d0..86f87f55513d1 100644
--- a/drivers/gpu/drm/msm/msm_fbdev.c
+++ b/drivers/gpu/drm/msm/msm_fbdev.c
@@ -7,7 +7,6 @@
 #include 
 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -164,63 +163,12 @@ static const struct drm_fb_helper_funcs 
msm_fb_helper_funcs = {
 };
 
 /*
- * struct drm_client
+ * struct drm_client_funcs
  */
 
-static void msm_fbdev_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-
-   if (fb_helper->info) {
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_client_release(_helper->client);
-   drm_fb_helper_unprepare(fb_helper);
-   kfree(fb_helper);
-   }
-}
-
-static int msm_fbdev_client_restore(struct drm_client_dev *client)
-{
-   drm_fb_helper_lastclose(client->dev);
-
-   return 0;
-}
-
-static int msm_fbdev_client_hotplug(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = client->dev;
-   int ret;
-
-   if (dev->fb_helper)
-   return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-   ret = drm_fb_helper_init(dev, fb_helper);
-   if (ret)
-   goto err_drm_err;
-
-   if (!drm_drv_uses_atomic_modeset(dev))
-   drm_helper_disable_unused_functions(dev);
-
-   ret = drm_fb_helper_initial_config(fb_helper);
-   if (ret)
-   goto err_drm_fb_helper_fini;
-
-   return 0;
-
-err_drm_fb_helper_fini:
-   drm_fb_helper_fini(fb_helper);
-err_drm_err:
-   drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret);
-   return ret;
-}
-
 static const struct drm_client_funcs msm_fbdev_client_funcs = {
-   .owner  = THIS_MODULE,
-   .unregister = msm_fbdev_client_unregister,
-   .restore= msm_fbdev_client_restore,
-   .hotplug= msm_fbdev_client_hotplug,
+   .owner = THIS_MODULE,
+   DRM_FBDEV_HELPER_CLIENT_FUNCS,
 };
 
 /* initialize fbdev helper */
-- 
2.44.0



[PATCH 08/11] drm/i915: Use drm_fbdev_helper_client_unregister()

2024-05-07 Thread Thomas Zimmermann
Implement struct drm_client_funcs.unregister with the helpers
drm_fbdev_helper_client_unregister() and remove the custom code
from the driver. The generic helper is equivalent in functionality.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/i915/display/intel_fbdev.c | 21 ++---
 1 file changed, 2 insertions(+), 19 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c 
b/drivers/gpu/drm/i915/display/intel_fbdev.c
index bda702c2cab8e..f1b4543bffc02 100644
--- a/drivers/gpu/drm/i915/display/intel_fbdev.c
+++ b/drivers/gpu/drm/i915/display/intel_fbdev.c
@@ -38,7 +38,6 @@
 #include 
 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -580,25 +579,9 @@ static int intel_fbdev_restore_mode(struct 
drm_i915_private *dev_priv)
 }
 
 /*
- * Fbdev client and struct drm_client_funcs
+ * struct drm_client_funcs
  */
 
-static void intel_fbdev_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = fb_helper->dev;
-   struct pci_dev *pdev = to_pci_dev(dev->dev);
-
-   if (fb_helper->info) {
-   vga_switcheroo_client_fb_set(pdev, NULL);
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_fb_helper_unprepare(fb_helper);
-   drm_client_release(_helper->client);
-   kfree(fb_helper);
-   }
-}
-
 static int intel_fbdev_client_restore(struct drm_client_dev *client)
 {
struct drm_i915_private *dev_priv = to_i915(client->dev);
@@ -644,7 +627,7 @@ static int intel_fbdev_client_hotplug(struct drm_client_dev 
*client)
 
 static const struct drm_client_funcs intel_fbdev_client_funcs = {
.owner  = THIS_MODULE,
-   .unregister = intel_fbdev_client_unregister,
+   .unregister = drm_fbdev_helper_client_unregister,
.restore= intel_fbdev_client_restore,
.hotplug= intel_fbdev_client_hotplug,
 };
-- 
2.44.0



[PATCH 05/11] drm/armada: Use fbdev client helpers

2024-05-07 Thread Thomas Zimmermann
Implement struct drm_client_funcs with the respective helpers and
remove the custom code from the emulation. The generic helpers are
equivalent in functionality.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/armada/armada_fbdev.c | 58 ++-
 1 file changed, 3 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/armada/armada_fbdev.c 
b/drivers/gpu/drm/armada/armada_fbdev.c
index d223176912b63..68d4fc0e47268 100644
--- a/drivers/gpu/drm/armada/armada_fbdev.c
+++ b/drivers/gpu/drm/armada/armada_fbdev.c
@@ -9,7 +9,6 @@
 #include 
 #include 
 
-#include 
 #include 
 #include 
 #include 
@@ -131,63 +130,12 @@ static const struct drm_fb_helper_funcs 
armada_fb_helper_funcs = {
 };
 
 /*
- * Fbdev client and struct drm_client_funcs
+ * struct drm_client_funcs
  */
 
-static void armada_fbdev_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fbh = drm_fb_helper_from_client(client);
-
-   if (fbh->info) {
-   drm_fb_helper_unregister_info(fbh);
-   } else {
-   drm_client_release(>client);
-   drm_fb_helper_unprepare(fbh);
-   kfree(fbh);
-   }
-}
-
-static int armada_fbdev_client_restore(struct drm_client_dev *client)
-{
-   drm_fb_helper_lastclose(client->dev);
-
-   return 0;
-}
-
-static int armada_fbdev_client_hotplug(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fbh = drm_fb_helper_from_client(client);
-   struct drm_device *dev = client->dev;
-   int ret;
-
-   if (dev->fb_helper)
-   return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-   ret = drm_fb_helper_init(dev, fbh);
-   if (ret)
-   goto err_drm_err;
-
-   if (!drm_drv_uses_atomic_modeset(dev))
-   drm_helper_disable_unused_functions(dev);
-
-   ret = drm_fb_helper_initial_config(fbh);
-   if (ret)
-   goto err_drm_fb_helper_fini;
-
-   return 0;
-
-err_drm_fb_helper_fini:
-   drm_fb_helper_fini(fbh);
-err_drm_err:
-   drm_err(dev, "armada: Failed to setup fbdev emulation (ret=%d)\n", ret);
-   return ret;
-}
-
 static const struct drm_client_funcs armada_fbdev_client_funcs = {
-   .owner  = THIS_MODULE,
-   .unregister = armada_fbdev_client_unregister,
-   .restore= armada_fbdev_client_restore,
-   .hotplug= armada_fbdev_client_hotplug,
+   .owner = THIS_MODULE,
+   DRM_FBDEV_HELPER_CLIENT_FUNCS,
 };
 
 void armada_fbdev_setup(struct drm_device *dev)
-- 
2.44.0



[PATCH 07/11] drm/gma500: Use fbdev client helpers

2024-05-07 Thread Thomas Zimmermann
Implement struct drm_client_funcs with the respective helpers and
remove the custom code from the emulation. The generic helpers are
equivalent in functionality.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/gma500/fbdev.c | 58 ++
 1 file changed, 3 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/gma500/fbdev.c b/drivers/gpu/drm/gma500/fbdev.c
index 98b44974d42dd..8a6cb47e83f8f 100644
--- a/drivers/gpu/drm/gma500/fbdev.c
+++ b/drivers/gpu/drm/gma500/fbdev.c
@@ -8,7 +8,6 @@
 #include 
 #include 
 
-#include 
 #include 
 #include 
 #include 
@@ -252,63 +251,12 @@ static const struct drm_fb_helper_funcs 
psb_fbdev_fb_helper_funcs = {
 };
 
 /*
- * struct drm_client_funcs and setup code
+ * struct drm_client_funcs
  */
 
-static void psb_fbdev_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-
-   if (fb_helper->info) {
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_fb_helper_unprepare(fb_helper);
-   drm_client_release(_helper->client);
-   kfree(fb_helper);
-   }
-}
-
-static int psb_fbdev_client_restore(struct drm_client_dev *client)
-{
-   drm_fb_helper_lastclose(client->dev);
-
-   return 0;
-}
-
-static int psb_fbdev_client_hotplug(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = client->dev;
-   int ret;
-
-   if (dev->fb_helper)
-   return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-   ret = drm_fb_helper_init(dev, fb_helper);
-   if (ret)
-   goto err_drm_err;
-
-   if (!drm_drv_uses_atomic_modeset(dev))
-   drm_helper_disable_unused_functions(dev);
-
-   ret = drm_fb_helper_initial_config(fb_helper);
-   if (ret)
-   goto err_drm_fb_helper_fini;
-
-   return 0;
-
-err_drm_fb_helper_fini:
-   drm_fb_helper_fini(fb_helper);
-err_drm_err:
-   drm_err(dev, "Failed to setup gma500 fbdev emulation (ret=%d)\n", ret);
-   return ret;
-}
-
 static const struct drm_client_funcs psb_fbdev_client_funcs = {
-   .owner  = THIS_MODULE,
-   .unregister = psb_fbdev_client_unregister,
-   .restore= psb_fbdev_client_restore,
-   .hotplug= psb_fbdev_client_hotplug,
+   .owner = THIS_MODULE,
+   DRM_FBDEV_HELPER_CLIENT_FUNCS,
 };
 
 void psb_fbdev_setup(struct drm_psb_private *dev_priv)
-- 
2.44.0



[PATCH 06/11] drm/exynos: Use fbdev client helpers

2024-05-07 Thread Thomas Zimmermann
Implement struct drm_client_funcs with the respective helpers and
remove the custom code from the emulation. The generic helpers are
equivalent in functionality.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c | 58 ++-
 1 file changed, 3 insertions(+), 55 deletions(-)

diff --git a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c 
b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
index a379c8ca435a3..982754008a803 100644
--- a/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
+++ b/drivers/gpu/drm/exynos/exynos_drm_fbdev.c
@@ -10,7 +10,6 @@
 
 #include 
 
-#include 
 #include 
 #include 
 #include 
@@ -140,63 +139,12 @@ static const struct drm_fb_helper_funcs 
exynos_drm_fb_helper_funcs = {
 };
 
 /*
- * struct drm_client
+ * struct drm_client_funcs
  */
 
-static void exynos_drm_fbdev_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-
-   if (fb_helper->info) {
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_client_release(_helper->client);
-   drm_fb_helper_unprepare(fb_helper);
-   kfree(fb_helper);
-   }
-}
-
-static int exynos_drm_fbdev_client_restore(struct drm_client_dev *client)
-{
-   drm_fb_helper_lastclose(client->dev);
-
-   return 0;
-}
-
-static int exynos_drm_fbdev_client_hotplug(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = client->dev;
-   int ret;
-
-   if (dev->fb_helper)
-   return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-   ret = drm_fb_helper_init(dev, fb_helper);
-   if (ret)
-   goto err_drm_err;
-
-   if (!drm_drv_uses_atomic_modeset(dev))
-   drm_helper_disable_unused_functions(dev);
-
-   ret = drm_fb_helper_initial_config(fb_helper);
-   if (ret)
-   goto err_drm_fb_helper_fini;
-
-   return 0;
-
-err_drm_fb_helper_fini:
-   drm_fb_helper_fini(fb_helper);
-err_drm_err:
-   drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret);
-   return ret;
-}
-
 static const struct drm_client_funcs exynos_drm_fbdev_client_funcs = {
-   .owner  = THIS_MODULE,
-   .unregister = exynos_drm_fbdev_client_unregister,
-   .restore= exynos_drm_fbdev_client_restore,
-   .hotplug= exynos_drm_fbdev_client_hotplug,
+   .owner = THIS_MODULE,
+   DRM_FBDEV_HELPER_CLIENT_FUNCS,
 };
 
 void exynos_drm_fbdev_setup(struct drm_device *dev)
-- 
2.44.0



[PATCH 00/11] drm: Provide common fbdev client helpers

2024-05-07 Thread Thomas Zimmermann
All fbdev emulation has finally been converted to use struct
drm_client. Put the common client code into shared helpers.

There are three callbacks in struct drm_client_funcs, unregister,
restore and hotplug, which have similar implementations among the
various drivers. This can all be shared. i915 is slightly different,
but can still use some of the helper code.

Fbdev support for VGA switcheroo and non-atomic mode setting is now
entirely implemented in the fbdev helpers.

Thomas Zimmermann (11):
  drm/fb-helper: Add helpers for struct drm_client_funcs
  drm/fbdev-dma: Use fbdev client helpers
  drm/fbdev-shmem: Use fbdev client helpers
  drm/fbdev-ttm: Use fbdev client helpers
  drm/armada: Use fbdev client helpers
  drm/exynos: Use fbdev client helpers
  drm/gma500: Use fbdev client helpers
  drm/i915: Use drm_fbdev_helper_client_unregister()
  drm/msm: Use fbdev client helpers
  drm/omapdrm: Use fbdev client helpers
  drm/tegra: Use fbdev client helpers

 drivers/gpu/drm/armada/armada_fbdev.c  |  58 +---
 drivers/gpu/drm/drm_fb_helper.c| 103 +
 drivers/gpu/drm/drm_fbdev_dma.c|  56 +--
 drivers/gpu/drm/drm_fbdev_shmem.c  |  56 +--
 drivers/gpu/drm/drm_fbdev_ttm.c|  58 +---
 drivers/gpu/drm/exynos/exynos_drm_fbdev.c  |  58 +---
 drivers/gpu/drm/gma500/fbdev.c |  58 +---
 drivers/gpu/drm/i915/display/intel_fbdev.c |  21 +
 drivers/gpu/drm/msm/msm_fbdev.c|  58 +---
 drivers/gpu/drm/omapdrm/omap_fbdev.c   |  55 +--
 drivers/gpu/drm/radeon/radeon_fbdev.c  |  66 +
 drivers/gpu/drm/tegra/fbdev.c  |  58 +---
 include/drm/drm_fb_helper.h|  19 
 13 files changed, 154 insertions(+), 570 deletions(-)


base-commit: 980de4c8f9c4fc65bd51d355372e06dc576c3ea7
-- 
2.44.0



[PATCH 01/11] drm/fb-helper: Add helpers for struct drm_client_funcs

2024-05-07 Thread Thomas Zimmermann
Add default implementations for unregister, restore and hotplug of
struct drm_client_funcs. The provided helpers are compatible with the
requirements of most DRM drivers.

The helpers handle support for VGA switcheroo automatically. With
DRM drivers that don't implement VGA switcheroo, this does nothing.

The helpers also support DRM drivers with non-atomic mode setting,
which require additional steps to disable their modesetting pipeline.

Compared to its current implementations in various drivers, there
is one difference in drm_fbdev_helper_client_hotplug(). The custom
functions perform hotpluging if struct drm_device.fb_helper has been
set, while the custom helper tests for struct drm_fb_helper.info.
Both fields signal the presence of an active fbdev emulation, but
the former field is deprecated.

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

diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index e2e19f49342e1..005debf61a571 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -35,6 +35,7 @@
 #include 
 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -2013,3 +2014,105 @@ void drm_fb_helper_output_poll_changed(struct 
drm_device *dev)
drm_fb_helper_hotplug_event(dev->fb_helper);
 }
 EXPORT_SYMBOL(drm_fb_helper_output_poll_changed);
+
+/*
+ * struct drm_client_funcs
+ */
+
+/**
+ * drm_fbdev_helper_client_unregister - Unregister callback for fbdev emulation
+ * @client: The fbdev client
+ *
+ * Implements struct drm_client_funcs.unregister for fbdev emulation. The
+ * helper destroys the framebuffer device and releases all resources. It
+ * further disables all outputs and clears the VGA switcheroo framebuffer
+ * info for PCI devices.
+ */
+void drm_fbdev_helper_client_unregister(struct drm_client_dev *client)
+{
+   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+   struct drm_device *dev = fb_helper->dev;
+
+   if (fb_helper->info) {
+   if (dev_is_pci(dev->dev))
+   vga_switcheroo_client_fb_set(to_pci_dev(dev->dev), 
NULL);
+   drm_fb_helper_unregister_info(fb_helper);
+   if (!drm_drv_uses_atomic_modeset(dev))
+   drm_helper_force_disable_all(dev);
+   } else {
+   drm_client_release(client);
+   drm_fb_helper_unprepare(fb_helper);
+   kfree(fb_helper);
+   }
+}
+EXPORT_SYMBOL(drm_fbdev_helper_client_unregister);
+
+/**
+ * drm_fbdev_helper_client_restore - Restore callback for fbdev emulation
+ * @client: The fbdev client
+ *
+ * Implements struct drm_client_funcs.restore for fbdev emulation. The
+ * helper restores the console output after the fbdev emulation's current
+ * configuration. It also informs VGA switcheroo about the change.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise.
+ */
+int drm_fbdev_helper_client_restore(struct drm_client_dev *client)
+{
+   struct drm_device *dev = client->dev;
+
+   drm_fb_helper_lastclose(dev);
+
+   if (dev_is_pci(dev->dev))
+   vga_switcheroo_process_delayed_switch();
+
+   return 0;
+}
+EXPORT_SYMBOL(drm_fbdev_helper_client_restore);
+
+/**
+ * drm_fbdev_helper_client_hotplug - Hotplug callback for fbdev emulation
+ * @client: The fbdev client
+ *
+ * Implements struct drm_client_funcs.hotplug for fbdev emulation. The
+ * helper handles the hotplugging event by restoring the display output.
+ * If no output has been established yet, it instead performs an initial
+ * display configuration. On successful configuration, it installs the
+ * framebuffer info VGA switcheroo for PCI devices.
+ *
+ * Returns:
+ * 0 on success, or a negative errno code otherwise.
+ */
+int drm_fbdev_helper_client_hotplug(struct drm_client_dev *client)
+{
+   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
+   struct drm_device *dev = client->dev;
+   int ret;
+
+   if (fb_helper->info)
+   return drm_fb_helper_hotplug_event(fb_helper);
+
+   ret = drm_fb_helper_init(dev, fb_helper);
+   if (ret)
+   goto err_drm_err;
+
+   if (!drm_drv_uses_atomic_modeset(dev))
+   drm_helper_disable_unused_functions(dev);
+
+   ret = drm_fb_helper_initial_config(fb_helper);
+   if (ret)
+   goto err_drm_fb_helper_fini;
+
+   if (dev_is_pci(dev->dev))
+   vga_switcheroo_client_fb_set(to_pci_dev(dev->dev), 
fb_helper->info);
+
+   return 0;
+
+err_drm_fb_helper_fini:
+   drm_fb_helper_fini(fb_helper);
+err_drm_err:
+   drm_err(dev, "Failed to setup fbdev emulation (ret=%d)\n", ret);
+   return ret;
+}
+EXPORT_SYMBOL(drm_fbdev_helper_client_hotplug);
diff --git a/include/drm/drm_f

[PATCH 04/11] drm/fbdev-ttm: Use fbdev client helpers

2024-05-07 Thread Thomas Zimmermann
Implement struct drm_client_funcs with the respective helpers and
remove the custom code from the emulation. The generic helpers are
equivalent in functionality.

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

diff --git a/drivers/gpu/drm/drm_fbdev_ttm.c b/drivers/gpu/drm/drm_fbdev_ttm.c
index bb7898cd7dc63..b1c5ebe6b9588 100644
--- a/drivers/gpu/drm/drm_fbdev_ttm.c
+++ b/drivers/gpu/drm/drm_fbdev_ttm.c
@@ -3,7 +3,6 @@
 #include 
 #include 
 
-#include 
 #include 
 #include 
 #include 
@@ -239,60 +238,13 @@ static const struct drm_fb_helper_funcs 
drm_fbdev_ttm_helper_funcs = {
.fb_dirty = drm_fbdev_ttm_helper_fb_dirty,
 };
 
-static void drm_fbdev_ttm_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-
-   if (fb_helper->info) {
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_client_release(_helper->client);
-   drm_fb_helper_unprepare(fb_helper);
-   kfree(fb_helper);
-   }
-}
-
-static int drm_fbdev_ttm_client_restore(struct drm_client_dev *client)
-{
-   drm_fb_helper_lastclose(client->dev);
-
-   return 0;
-}
-
-static int drm_fbdev_ttm_client_hotplug(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = client->dev;
-   int ret;
-
-   if (dev->fb_helper)
-   return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-   ret = drm_fb_helper_init(dev, fb_helper);
-   if (ret)
-   goto err_drm_err;
-
-   if (!drm_drv_uses_atomic_modeset(dev))
-   drm_helper_disable_unused_functions(dev);
-
-   ret = drm_fb_helper_initial_config(fb_helper);
-   if (ret)
-   goto err_drm_fb_helper_fini;
-
-   return 0;
-
-err_drm_fb_helper_fini:
-   drm_fb_helper_fini(fb_helper);
-err_drm_err:
-   drm_err(dev, "fbdev: Failed to setup emulation (ret=%d)\n", ret);
-   return ret;
-}
+/*
+ * struct drm_client_funcs
+ */
 
 static const struct drm_client_funcs drm_fbdev_ttm_client_funcs = {
-   .owner  = THIS_MODULE,
-   .unregister = drm_fbdev_ttm_client_unregister,
-   .restore= drm_fbdev_ttm_client_restore,
-   .hotplug= drm_fbdev_ttm_client_hotplug,
+   .owner = THIS_MODULE,
+   DRM_FBDEV_HELPER_CLIENT_FUNCS,
 };
 
 /**
-- 
2.44.0



[PATCH 03/11] drm/fbdev-shmem: Use fbdev client helpers

2024-05-07 Thread Thomas Zimmermann
Implement struct drm_client_funcs with the respective helpers and
remove the custom code from the emulation. The generic helpers are
equivalent in functionality.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_fbdev_shmem.c | 56 ++-
 1 file changed, 2 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/drm_fbdev_shmem.c 
b/drivers/gpu/drm/drm_fbdev_shmem.c
index a85a8a8e2eb8b..475e2c228d97f 100644
--- a/drivers/gpu/drm/drm_fbdev_shmem.c
+++ b/drivers/gpu/drm/drm_fbdev_shmem.c
@@ -2,7 +2,6 @@
 
 #include 
 
-#include 
 #include 
 #include 
 #include 
@@ -210,60 +209,9 @@ static const struct drm_fb_helper_funcs 
drm_fbdev_shmem_helper_funcs = {
  * struct drm_client_funcs
  */
 
-static void drm_fbdev_shmem_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-
-   if (fb_helper->info) {
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_client_release(_helper->client);
-   drm_fb_helper_unprepare(fb_helper);
-   kfree(fb_helper);
-   }
-}
-
-static int drm_fbdev_shmem_client_restore(struct drm_client_dev *client)
-{
-   drm_fb_helper_lastclose(client->dev);
-
-   return 0;
-}
-
-static int drm_fbdev_shmem_client_hotplug(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = client->dev;
-   int ret;
-
-   if (dev->fb_helper)
-   return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-   ret = drm_fb_helper_init(dev, fb_helper);
-   if (ret)
-   goto err_drm_err;
-
-   if (!drm_drv_uses_atomic_modeset(dev))
-   drm_helper_disable_unused_functions(dev);
-
-   ret = drm_fb_helper_initial_config(fb_helper);
-   if (ret)
-   goto err_drm_fb_helper_fini;
-
-   return 0;
-
-err_drm_fb_helper_fini:
-   drm_fb_helper_fini(fb_helper);
-err_drm_err:
-   drm_err(dev, "fbdev-shmem: Failed to setup emulation (ret=%d)\n", ret);
-   return ret;
-}
-
 static const struct drm_client_funcs drm_fbdev_shmem_client_funcs = {
-   .owner  = THIS_MODULE,
-   .unregister = drm_fbdev_shmem_client_unregister,
-   .restore= drm_fbdev_shmem_client_restore,
-   .hotplug= drm_fbdev_shmem_client_hotplug,
+   .owner = THIS_MODULE,
+   DRM_FBDEV_HELPER_CLIENT_FUNCS,
 };
 
 /**
-- 
2.44.0



[PATCH 02/11] drm/fbdev-dma: Use fbdev client helpers

2024-05-07 Thread Thomas Zimmermann
Implement struct drm_client_funcs with the respective helpers and
remove the custom code from the emulation. The generic helpers are
equivalent in functionality.

Signed-off-by: Thomas Zimmermann 
---
 drivers/gpu/drm/drm_fbdev_dma.c | 56 ++---
 1 file changed, 2 insertions(+), 54 deletions(-)

diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c
index 5eeb5164e9e2b..7991e37f000e7 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -2,7 +2,6 @@
 
 #include 
 
-#include 
 #include 
 #include 
 #include 
@@ -189,60 +188,9 @@ static const struct drm_fb_helper_funcs 
drm_fbdev_dma_helper_funcs = {
  * struct drm_client_funcs
  */
 
-static void drm_fbdev_dma_client_unregister(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-
-   if (fb_helper->info) {
-   drm_fb_helper_unregister_info(fb_helper);
-   } else {
-   drm_client_release(_helper->client);
-   drm_fb_helper_unprepare(fb_helper);
-   kfree(fb_helper);
-   }
-}
-
-static int drm_fbdev_dma_client_restore(struct drm_client_dev *client)
-{
-   drm_fb_helper_lastclose(client->dev);
-
-   return 0;
-}
-
-static int drm_fbdev_dma_client_hotplug(struct drm_client_dev *client)
-{
-   struct drm_fb_helper *fb_helper = drm_fb_helper_from_client(client);
-   struct drm_device *dev = client->dev;
-   int ret;
-
-   if (dev->fb_helper)
-   return drm_fb_helper_hotplug_event(dev->fb_helper);
-
-   ret = drm_fb_helper_init(dev, fb_helper);
-   if (ret)
-   goto err_drm_err;
-
-   if (!drm_drv_uses_atomic_modeset(dev))
-   drm_helper_disable_unused_functions(dev);
-
-   ret = drm_fb_helper_initial_config(fb_helper);
-   if (ret)
-   goto err_drm_fb_helper_fini;
-
-   return 0;
-
-err_drm_fb_helper_fini:
-   drm_fb_helper_fini(fb_helper);
-err_drm_err:
-   drm_err(dev, "fbdev-dma: Failed to setup generic emulation (ret=%d)\n", 
ret);
-   return ret;
-}
-
 static const struct drm_client_funcs drm_fbdev_dma_client_funcs = {
-   .owner  = THIS_MODULE,
-   .unregister = drm_fbdev_dma_client_unregister,
-   .restore= drm_fbdev_dma_client_restore,
-   .hotplug= drm_fbdev_dma_client_hotplug,
+   .owner = THIS_MODULE,
+   DRM_FBDEV_HELPER_CLIENT_FUNCS,
 };
 
 /**
-- 
2.44.0



Re: [PATCH v2 12/12] fbdev/viafb: Make I2C terminology more inclusive

2024-05-06 Thread Thomas Zimmermann




Am 03.05.24 um 20:13 schrieb Easwar Hariharan:

I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave"
with more appropriate terms. Inspired by and following on to Wolfram's
series to fix drivers/i2c/[1], fix the terminology for users of
I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists
in the specification.

Compile tested, no functionality changes intended

[1]: 
https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/

Signed-off-by: Easwar Hariharan 


Acked-by: Thomas Zimmermann 


---
  drivers/video/fbdev/via/chip.h|  8 
  drivers/video/fbdev/via/dvi.c | 24 
  drivers/video/fbdev/via/lcd.c |  6 +++---
  drivers/video/fbdev/via/via_aux.h |  2 +-
  drivers/video/fbdev/via/via_i2c.c | 12 ++--
  drivers/video/fbdev/via/vt1636.c  |  6 +++---
  6 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/video/fbdev/via/chip.h b/drivers/video/fbdev/via/chip.h
index f0a19cbcb9e5..f81af13630e2 100644
--- a/drivers/video/fbdev/via/chip.h
+++ b/drivers/video/fbdev/via/chip.h
@@ -69,7 +69,7 @@
  #define VT1632_TMDS 0x01
  #define INTEGRATED_TMDS 0x42
  
-/* Definition TMDS Trasmitter I2C Slave Address */

+/* Definition TMDS Trasmitter I2C Target Address */
  #define VT1632_TMDS_I2C_ADDR0x10
  
  /**/

@@ -88,21 +88,21 @@
  #define TX_DATA_DDR_MODE0x04
  #define TX_DATA_SDR_MODE0x08
  
-/* Definition LVDS Trasmitter I2C Slave Address */

+/* Definition LVDS Trasmitter I2C Target Address */
  #define VT1631_LVDS_I2C_ADDR0x70
  #define VT3271_LVDS_I2C_ADDR0x80
  #define VT1636_LVDS_I2C_ADDR0x80
  
  struct tmds_chip_information {

int tmds_chip_name;
-   int tmds_chip_slave_addr;
+   int tmds_chip_target_addr;
int output_interface;
int i2c_port;
  };
  
  struct lvds_chip_information {

int lvds_chip_name;
-   int lvds_chip_slave_addr;
+   int lvds_chip_target_addr;
int output_interface;
int i2c_port;
  };
diff --git a/drivers/video/fbdev/via/dvi.c b/drivers/video/fbdev/via/dvi.c
index 13147e3066eb..27990a73bfa3 100644
--- a/drivers/video/fbdev/via/dvi.c
+++ b/drivers/video/fbdev/via/dvi.c
@@ -70,7 +70,7 @@ bool viafb_tmds_trasmitter_identify(void)
/* Check for VT1632: */
viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
viaparinfo->chip_info->
-   tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
+   tmds_chip_info.tmds_chip_target_addr = VT1632_TMDS_I2C_ADDR;
viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31;
if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) {
/*
@@ -128,14 +128,14 @@ bool viafb_tmds_trasmitter_identify(void)
viaparinfo->chip_info->
tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
viaparinfo->chip_info->tmds_chip_info.
-   tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
+   tmds_chip_target_addr = VT1632_TMDS_I2C_ADDR;
return false;
  }
  
  static void tmds_register_write(int index, u8 data)

  {
viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port,
-   
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
+   
viaparinfo->chip_info->tmds_chip_info.tmds_chip_target_addr,
index, data);
  }
  
@@ -144,7 +144,7 @@ static int tmds_register_read(int index)

u8 data;
  
  	viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port,

-  (u8) 
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
+  (u8) 
viaparinfo->chip_info->tmds_chip_info.tmds_chip_target_addr,
   (u8) index, );
return data;
  }
@@ -152,7 +152,7 @@ static int tmds_register_read(int index)
  static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
  {
viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port,
-   (u8) 
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
+   (u8) 
viaparinfo->chip_info->tmds_chip_info.tmds_chip_target_addr,
(u8) index, buff, buff_len);
return 0;
  }
@@ -256,14 +256,14 @@ static int viafb_dvi_query_EDID(void)
  
  	DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
  
-	restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;

-   viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+   restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_target_addr;
+   viaparinfo->chip_info->tmds_ch

Re: [PATCH v2 11/12] fbdev/smscufx: Make I2C terminology more inclusive

2024-05-06 Thread Thomas Zimmermann




Am 03.05.24 um 20:13 schrieb Easwar Hariharan:

I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave"
with more appropriate terms. Inspired by and following on to Wolfram's
series to fix drivers/i2c/[1], fix the terminology for users of
I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists
in the specification.

Compile tested, no functionality changes intended

[1]: 
https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/

Signed-off-by: Easwar Hariharan 


Acked-by: Thomas Zimmermann 


---
  drivers/video/fbdev/smscufx.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index 35d682b110c4..5f0dd01fd834 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1292,7 +1292,7 @@ static int ufx_realloc_framebuffer(struct ufx_data *dev, 
struct fb_info *info)
return 0;
  }
  
-/* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, master,

+/* sets up DDC channel for 100 Kbps, std. speed, 7-bit addr, controller mode,
   * restart enabled, but no start byte, enable controller */
  static int ufx_i2c_init(struct ufx_data *dev)
  {
@@ -1321,7 +1321,7 @@ static int ufx_i2c_init(struct ufx_data *dev)
/* 7-bit (not 10-bit) addressing */
tmp &= ~(0x10);
  
-	/* enable restart conditions and master mode */

+   /* enable restart conditions and controller mode */
tmp |= 0x21;
  
  	status = ufx_reg_write(dev, 0x1000, tmp);


--
--
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 v3 0/3] arch: Remove fbdev dependency from video helpers

2024-05-03 Thread Thomas Zimmermann




Am 03.05.24 um 17:29 schrieb Arnd Bergmann:

On Fri, Apr 5, 2024, at 11:04, Thomas Zimmermann wrote:

Hi,

if there are no further comments, can this series be merged through
asm-generic?

Sorry for the delay, I've merged these for asm-generic now.


Thank you so much!



   Arnd



--
--
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 v1 12/12] fbdev/viafb: Make I2C terminology more inclusive

2024-05-03 Thread Thomas Zimmermann

Hi

Am 03.05.24 um 00:26 schrieb Easwar Hariharan:

On 5/2/2024 3:46 AM, Thomas Zimmermann wrote:


Am 30.04.24 um 19:38 schrieb Easwar Hariharan:

I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave"
with more appropriate terms. Inspired by and following on to Wolfram's
series to fix drivers/i2c/[1], fix the terminology for users of
I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists
in the specification.

Compile tested, no functionality changes intended

[1]: 
https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/

Signed-off-by: Easwar Hariharan 

Acked-by: Thomas Zimmermann 


Thanks for the ack! I had been addressing feedback as I got it on the v0 
series, and it seems
I missed out on updating viafb and smscufx to spec-compliant controller/target 
terminology like
the v0->v1 changelog calls out before posting v1.

For smscufx, I feel phrasing the following line (as an example)


-/* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, host,
+/* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, *controller*,

would actually impact readability negatively, so I propose to leave smscufx as 
is.


Why? I don't see much of a difference.



For viafb, I propose making it compliant with the spec using the 
controller/target terminology and
posting a v2 respin (which I can send out as soon as you say) and ask you to 
review again.

What do you think?


I think we should adopt the spec's language everywhere. That makes it 
possible to grep the spec for terms used in the source code. Using 
'host' in smscufx appears to introduce yet another term. If you are 
worried about using 'I2C controller' and 'controller' in the same 
sentence, you can replace 'I2C controller' with 'DDC channel'. That's 
even more precise about the purpose of this code.


Best regards
Thomas



Thanks,
Easwar


---
   drivers/video/fbdev/via/chip.h    |  8 
   drivers/video/fbdev/via/dvi.c | 24 
   drivers/video/fbdev/via/lcd.c |  6 +++---
   drivers/video/fbdev/via/via_aux.h |  2 +-
   drivers/video/fbdev/via/via_i2c.c | 12 ++--
   drivers/video/fbdev/via/vt1636.c  |  6 +++---
   6 files changed, 29 insertions(+), 29 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)



[PULL] drm-misc-fixes

2024-05-02 Thread Thomas Zimmermann
Hi Dave, Sima,

here's the PR for drm-misc-fixes for this week.

Best regards
Thomas

drm-misc-fixes-2024-05-02:
Short summary of fixes pull:

imagination:
- fix page-count macro

nouveau:
- avoid page-table allocation failures
- fix firmware memory allocation

panel:
- ili9341: avoid OF for device properties; respect deferred probe; fix
usage of errno codes

ttm:
- fix status output

vmwgfx:
- fix legacy display unit
- fix read length in fence signalling
The following changes since commit 78d9161d2bcd442d93d917339297ffa057dbee8c:

  fbdev: fix incorrect address computation in deferred IO (2024-04-24 15:03:37 
+0200)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/misc/kernel.git 
tags/drm-misc-fixes-2024-05-02

for you to fetch changes up to da85f0aaa9f21999753b01d45c0343f885a8f905:

  drm/panel: ili9341: Use predefined error codes (2024-05-02 09:41:27 +0200)


Short summary of fixes pull:

imagination:
- fix page-count macro

nouveau:
- avoid page-table allocation failures
- fix firmware memory allocation

panel:
- ili9341: avoid OF for device properties; respect deferred probe; fix
usage of errno codes

ttm:
- fix status output

vmwgfx:
- fix legacy display unit
- fix read length in fence signalling


Andy Shevchenko (3):
  drm/panel: ili9341: Correct use of device property APIs
  drm/panel: ili9341: Respect deferred probe
  drm/panel: ili9341: Use predefined error codes

Ian Forbes (1):
  drm/vmwgfx: Fix Legacy Display Unit

Lyude Paul (2):
  drm/nouveau/firmware: Fix SG_DEBUG error with nvkm_firmware_ctor()
  drm/nouveau/gsp: Use the sg allocator for level 2 of radix3

Matt Coster (1):
  drm/imagination: Ensure PVR_MIPS_PT_PAGE_COUNT is never zero

Zack Rusin (2):
  drm/ttm: Print the memory decryption status just once
  drm/vmwgfx: Fix invalid reads in fence signaled events

 drivers/gpu/drm/imagination/pvr_fw_mips.h |  5 +-
 drivers/gpu/drm/nouveau/include/nvkm/subdev/gsp.h |  4 +-
 drivers/gpu/drm/nouveau/nvkm/core/firmware.c  | 19 +++---
 drivers/gpu/drm/nouveau/nvkm/subdev/gsp/r535.c| 77 +++
 drivers/gpu/drm/panel/Kconfig |  2 +-
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c  | 13 ++--
 drivers/gpu/drm/ttm/ttm_tt.c  |  2 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_bo.c|  1 +
 drivers/gpu/drm/vmwgfx/vmwgfx_fence.c |  2 +-
 9 files changed, 80 insertions(+), 45 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)


Re: [PATCH v3 0/2] drm: Fix dma_resv deadlock at drm object pin time

2024-05-02 Thread Thomas Zimmermann

Hi

Am 02.05.24 um 14:00 schrieb Boris Brezillon:

On Thu, 2 May 2024 13:59:41 +0200
Boris Brezillon  wrote:


Hi Thomas,

On Thu, 2 May 2024 13:51:16 +0200
Thomas Zimmermann  wrote:


Hi,

ignoring my r-b on patch 1, I'd like to rethink the current patches in
general.

I think drm_gem_shmem_pin() should become the locked version of _pin(),
so that drm_gem_shmem_object_pin() can call it directly. The existing
_pin_unlocked() would not be needed any longer. Same for the _unpin()
functions. This change would also fix the consistency with the semantics
of the shmem _vmap() functions, which never take reservation locks.

There are only two external callers of drm_gem_shmem_pin(): the test
case and panthor. These assume that drm_gem_shmem_pin() acquires the
reservation lock. The test case should likely call drm_gem_pin()
instead. That would acquire the reservation lock and the test would
validate that shmem's pin helper integrates well into the overall GEM
framework. The way panthor uses drm_gem_shmem_pin() looks wrong to me.
For now, it could receive a wrapper that takes the lock and that's it.

I do agree that the current inconsistencies in the naming is
troublesome (sometimes _unlocked, sometimes _locked, with the version
without any suffix meaning either _locked or _unlocked depending on
what the suffixed version does), and that's the very reason I asked
Dmitry to address that in his shrinker series [1]. So, ideally I'd
prefer if patches from Dmitry's series were applied instead of
trying to fix that here (IIRC, we had an ack from Maxime).

With the link this time :-).

[1]https://lore.kernel.org/lkml/20240105184624.508603-1-dmitry.osipe...@collabora.com/T/


Thanks. I remember these patches. Somehow I thought they would have been 
merged already. I wasn't super happy about the naming changes in patch 
5, because the names of the GEM object callbacks do no longer correspond 
with their implementations. But anyway.


If we go that direction, we should here simply push drm_gem_shmem_pin() 
and drm_gem_shmem_unpin() into panthor and update the shmem tests with 
drm_gem_pin(). Panfrost and lima would call drm_gem_shmem_pin_locked(). 
IMHO we should not promote the use of drm_gem_shmem_object_*() 
functions, as they are meant to be callbacks for struct 
drm_gem_object_funcs. (Auto-generating them would be nice.)


Best regards
Thomas





Regards,

Boris


--
--
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 v3 0/2] drm: Fix dma_resv deadlock at drm object pin time

2024-05-02 Thread Thomas Zimmermann

Hi,

ignoring my r-b on patch 1, I'd like to rethink the current patches in 
general.


I think drm_gem_shmem_pin() should become the locked version of _pin(), 
so that drm_gem_shmem_object_pin() can call it directly. The existing 
_pin_unlocked() would not be needed any longer. Same for the _unpin() 
functions. This change would also fix the consistency with the semantics 
of the shmem _vmap() functions, which never take reservation locks.


There are only two external callers of drm_gem_shmem_pin(): the test 
case and panthor. These assume that drm_gem_shmem_pin() acquires the 
reservation lock. The test case should likely call drm_gem_pin() 
instead. That would acquire the reservation lock and the test would 
validate that shmem's pin helper integrates well into the overall GEM 
framework. The way panthor uses drm_gem_shmem_pin() looks wrong to me. 
For now, it could receive a wrapper that takes the lock and that's it.


Best regards
Thomas

Am 01.05.24 um 08:55 schrieb Adrián Larumbe:

This is v3 of 
https://lore.kernel.org/dri-devel/20240424090429.57de7...@collabora.com/

The goal of this patch series is fixing a deadlock upon locking the dma 
reservation
of a DRM gem object when pinning it, at a prime import operation.

Changes from v2:
  - Removed comment explaining reason why an already-locked
pin function replaced the locked variant inside Panfrost's
object pin callback.
  - Moved already-assigned attachment warning into generic
already-locked gem object pin function

Adrián Larumbe (2):
   drm/panfrost: Fix dma_resv deadlock at drm object pin time
   drm/gem-shmem: Add import attachment warning to locked pin function

  drivers/gpu/drm/drm_gem_shmem_helper.c  | 2 ++
  drivers/gpu/drm/lima/lima_gem.c | 2 +-
  drivers/gpu/drm/panfrost/panfrost_gem.c | 2 +-
  3 files changed, 4 insertions(+), 2 deletions(-)


base-commit: 75b68f22e39aafb22f3d8e3071e1aba73560788c


--
--
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 v3 1/2] drm/panfrost: Fix dma_resv deadlock at drm object pin time

2024-05-02 Thread Thomas Zimmermann

Hi

Am 01.05.24 um 08:55 schrieb Adrián Larumbe:

When Panfrost must pin an object that is being prepared a dma-buf
attachment for on behalf of another driver, the core drm gem object pinning
code already takes a lock on the object's dma reservation.

However, Panfrost GEM object's pinning callback would eventually try taking
the lock on the same dma reservation when delegating pinning of the object
onto the shmem subsystem, which led to a deadlock.

This can be shown by enabling CONFIG_DEBUG_WW_MUTEX_SLOWPATH, which throws
the following recursive locking situation:

weston/3440 is trying to acquire lock:
00e235a0 (reservation_ww_class_mutex){+.+.}-{3:3}, at: 
drm_gem_shmem_pin+0x34/0xb8 [drm_shmem_helper]
but task is already holding lock:
00e235a0 (reservation_ww_class_mutex){+.+.}-{3:3}, at: 
drm_gem_pin+0x2c/0x80 [drm]

Fix it by assuming the object's reservation had already been locked by the
time we reach panfrost_gem_pin.


Maybe say that the reservation lock has been taken in drm_gem_pin()



Do the same thing for the Lima driver, as it most likely suffers from the
same issue.


Please split this patch into one for panfrost and one for lima. To each 
patch, you can add


Reviewed-by: Thomas Zimmermann 

Best regards
Thomas



Cc: Thomas Zimmermann 
Cc: Dmitry Osipenko 
Cc: Boris Brezillon 
Cc: Steven Price 
Fixes: a78027847226 ("drm/gem: Acquire reservation lock in 
drm_gem_{pin/unpin}()")
Signed-off-by: Adrián Larumbe 
---
  drivers/gpu/drm/lima/lima_gem.c | 2 +-
  drivers/gpu/drm/panfrost/panfrost_gem.c | 2 +-
  2 files changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/lima/lima_gem.c b/drivers/gpu/drm/lima/lima_gem.c
index 7ea244d876ca..c4e0f9faaa47 100644
--- a/drivers/gpu/drm/lima/lima_gem.c
+++ b/drivers/gpu/drm/lima/lima_gem.c
@@ -185,7 +185,7 @@ static int lima_gem_pin(struct drm_gem_object *obj)
if (bo->heap_size)
return -EINVAL;
  
-	return drm_gem_shmem_pin(>base);

+   return drm_gem_shmem_object_pin(obj);
  }
  
  static int lima_gem_vmap(struct drm_gem_object *obj, struct iosys_map *map)

diff --git a/drivers/gpu/drm/panfrost/panfrost_gem.c 
b/drivers/gpu/drm/panfrost/panfrost_gem.c
index d47b40b82b0b..f268bd5c2884 100644
--- a/drivers/gpu/drm/panfrost/panfrost_gem.c
+++ b/drivers/gpu/drm/panfrost/panfrost_gem.c
@@ -192,7 +192,7 @@ static int panfrost_gem_pin(struct drm_gem_object *obj)
if (bo->is_heap)
return -EINVAL;
  
-	return drm_gem_shmem_pin(>base);

+   return drm_gem_shmem_object_pin(obj);
  }
  
  static enum drm_gem_object_status panfrost_gem_status(struct drm_gem_object *obj)


--
--
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 v1 12/12] fbdev/viafb: Make I2C terminology more inclusive

2024-05-02 Thread Thomas Zimmermann




Am 30.04.24 um 19:38 schrieb Easwar Hariharan:

I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave"
with more appropriate terms. Inspired by and following on to Wolfram's
series to fix drivers/i2c/[1], fix the terminology for users of
I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists
in the specification.

Compile tested, no functionality changes intended

[1]: 
https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/

Signed-off-by: Easwar Hariharan 


Acked-by: Thomas Zimmermann 


---
  drivers/video/fbdev/via/chip.h|  8 
  drivers/video/fbdev/via/dvi.c | 24 
  drivers/video/fbdev/via/lcd.c |  6 +++---
  drivers/video/fbdev/via/via_aux.h |  2 +-
  drivers/video/fbdev/via/via_i2c.c | 12 ++--
  drivers/video/fbdev/via/vt1636.c  |  6 +++---
  6 files changed, 29 insertions(+), 29 deletions(-)

diff --git a/drivers/video/fbdev/via/chip.h b/drivers/video/fbdev/via/chip.h
index f0a19cbcb9e5..1ea6d4ce79e7 100644
--- a/drivers/video/fbdev/via/chip.h
+++ b/drivers/video/fbdev/via/chip.h
@@ -69,7 +69,7 @@
  #define VT1632_TMDS 0x01
  #define INTEGRATED_TMDS 0x42
  
-/* Definition TMDS Trasmitter I2C Slave Address */

+/* Definition TMDS Trasmitter I2C Client Address */
  #define VT1632_TMDS_I2C_ADDR0x10
  
  /**/

@@ -88,21 +88,21 @@
  #define TX_DATA_DDR_MODE0x04
  #define TX_DATA_SDR_MODE0x08
  
-/* Definition LVDS Trasmitter I2C Slave Address */

+/* Definition LVDS Trasmitter I2C Client Address */
  #define VT1631_LVDS_I2C_ADDR0x70
  #define VT3271_LVDS_I2C_ADDR0x80
  #define VT1636_LVDS_I2C_ADDR0x80
  
  struct tmds_chip_information {

int tmds_chip_name;
-   int tmds_chip_slave_addr;
+   int tmds_chip_client_addr;
int output_interface;
int i2c_port;
  };
  
  struct lvds_chip_information {

int lvds_chip_name;
-   int lvds_chip_slave_addr;
+   int lvds_chip_client_addr;
int output_interface;
int i2c_port;
  };
diff --git a/drivers/video/fbdev/via/dvi.c b/drivers/video/fbdev/via/dvi.c
index 13147e3066eb..db7db26416c3 100644
--- a/drivers/video/fbdev/via/dvi.c
+++ b/drivers/video/fbdev/via/dvi.c
@@ -70,7 +70,7 @@ bool viafb_tmds_trasmitter_identify(void)
/* Check for VT1632: */
viaparinfo->chip_info->tmds_chip_info.tmds_chip_name = VT1632_TMDS;
viaparinfo->chip_info->
-   tmds_chip_info.tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
+   tmds_chip_info.tmds_chip_client_addr = VT1632_TMDS_I2C_ADDR;
viaparinfo->chip_info->tmds_chip_info.i2c_port = VIA_PORT_31;
if (check_tmds_chip(VT1632_DEVICE_ID_REG, VT1632_DEVICE_ID)) {
/*
@@ -128,14 +128,14 @@ bool viafb_tmds_trasmitter_identify(void)
viaparinfo->chip_info->
tmds_chip_info.tmds_chip_name = NON_TMDS_TRANSMITTER;
viaparinfo->chip_info->tmds_chip_info.
-   tmds_chip_slave_addr = VT1632_TMDS_I2C_ADDR;
+   tmds_chip_client_addr = VT1632_TMDS_I2C_ADDR;
return false;
  }
  
  static void tmds_register_write(int index, u8 data)

  {
viafb_i2c_writebyte(viaparinfo->chip_info->tmds_chip_info.i2c_port,
-   
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
+   
viaparinfo->chip_info->tmds_chip_info.tmds_chip_client_addr,
index, data);
  }
  
@@ -144,7 +144,7 @@ static int tmds_register_read(int index)

u8 data;
  
  	viafb_i2c_readbyte(viaparinfo->chip_info->tmds_chip_info.i2c_port,

-  (u8) 
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
+  (u8) 
viaparinfo->chip_info->tmds_chip_info.tmds_chip_client_addr,
   (u8) index, );
return data;
  }
@@ -152,7 +152,7 @@ static int tmds_register_read(int index)
  static int tmds_register_read_bytes(int index, u8 *buff, int buff_len)
  {
viafb_i2c_readbytes(viaparinfo->chip_info->tmds_chip_info.i2c_port,
-   (u8) 
viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr,
+   (u8) 
viaparinfo->chip_info->tmds_chip_info.tmds_chip_client_addr,
(u8) index, buff, buff_len);
return 0;
  }
@@ -256,14 +256,14 @@ static int viafb_dvi_query_EDID(void)
  
  	DEBUG_MSG(KERN_INFO "viafb_dvi_query_EDID!!\n");
  
-	restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr;

-   viaparinfo->chip_info->tmds_chip_info.tmds_chip_slave_addr = 0xA0;
+   restore = viaparinfo->chip_info->tmds_chip_info.tmds_chip_client_addr;
+   viaparinfo->chip_info->tmds_ch

Re: [PATCH v1 11/12] fbdev/smscufx: Make I2C terminology more inclusive

2024-05-02 Thread Thomas Zimmermann




Am 30.04.24 um 19:38 schrieb Easwar Hariharan:

I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave"
with more appropriate terms. Inspired by and following on to Wolfram's
series to fix drivers/i2c/[1], fix the terminology for users of
I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists
in the specification.

Compile tested, no functionality changes intended

[1]: 
https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/

Signed-off-by: Easwar Hariharan 


Acked-by: Thomas Zimmermann 


---
  drivers/video/fbdev/smscufx.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/video/fbdev/smscufx.c b/drivers/video/fbdev/smscufx.c
index 35d682b110c4..1c80c1a3d516 100644
--- a/drivers/video/fbdev/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
@@ -1292,7 +1292,7 @@ static int ufx_realloc_framebuffer(struct ufx_data *dev, 
struct fb_info *info)
return 0;
  }
  
-/* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, master,

+/* sets up I2C Controller for 100 Kbps, std. speed, 7-bit addr, host,
   * restart enabled, but no start byte, enable controller */
  static int ufx_i2c_init(struct ufx_data *dev)
  {
@@ -1321,7 +1321,7 @@ static int ufx_i2c_init(struct ufx_data *dev)
/* 7-bit (not 10-bit) addressing */
tmp &= ~(0x10);
  
-	/* enable restart conditions and master mode */

+   /* enable restart conditions and host mode */
tmp |= 0x21;
  
  	status = ufx_reg_write(dev, 0x1000, tmp);


--
--
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 v1 02/12] drm/gma500: Make I2C terminology more inclusive

2024-05-02 Thread Thomas Zimmermann




Am 30.04.24 um 19:38 schrieb Easwar Hariharan:

I2C v7, SMBus 3.2, and I3C 1.1.1 specifications have replaced "master/slave"
with more appropriate terms. Inspired by and following on to Wolfram's
series to fix drivers/i2c/[1], fix the terminology for users of
I2C_ALGOBIT bitbanging interface, now that the approved verbiage exists
in the specification.

Compile tested, no functionality changes intended

[1]: 
https://lore.kernel.org/all/20240322132619.6389-1-wsa+rene...@sang-engineering.com/

Signed-off-by: Easwar Hariharan 


Acked-by: Thomas Zimmermann 


---
  drivers/gpu/drm/gma500/cdv_intel_lvds.c |  2 +-
  drivers/gpu/drm/gma500/intel_bios.c | 22 ++---
  drivers/gpu/drm/gma500/intel_bios.h |  4 ++--
  drivers/gpu/drm/gma500/intel_gmbus.c|  2 +-
  drivers/gpu/drm/gma500/psb_drv.h|  2 +-
  drivers/gpu/drm/gma500/psb_intel_drv.h  |  2 +-
  drivers/gpu/drm/gma500/psb_intel_lvds.c |  4 ++--
  drivers/gpu/drm/gma500/psb_intel_sdvo.c | 26 -
  8 files changed, 32 insertions(+), 32 deletions(-)

diff --git a/drivers/gpu/drm/gma500/cdv_intel_lvds.c 
b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
index f08a6803dc18..c7652a02b42e 100644
--- a/drivers/gpu/drm/gma500/cdv_intel_lvds.c
+++ b/drivers/gpu/drm/gma500/cdv_intel_lvds.c
@@ -565,7 +565,7 @@ void cdv_intel_lvds_init(struct drm_device *dev,
dev->dev, "I2C bus registration failed.\n");
goto err_encoder_cleanup;
}
-   gma_encoder->i2c_bus->slave_addr = 0x2C;
+   gma_encoder->i2c_bus->target_addr = 0x2C;
dev_priv->lvds_i2c_bus = gma_encoder->i2c_bus;
  
  	/*

diff --git a/drivers/gpu/drm/gma500/intel_bios.c 
b/drivers/gpu/drm/gma500/intel_bios.c
index 8245b5603d2c..d5924ca3ed05 100644
--- a/drivers/gpu/drm/gma500/intel_bios.c
+++ b/drivers/gpu/drm/gma500/intel_bios.c
@@ -14,8 +14,8 @@
  #include "psb_intel_drv.h"
  #include "psb_intel_reg.h"
  
-#define	SLAVE_ADDR1	0x70

-#defineSLAVE_ADDR2 0x72
+#defineTARGET_ADDR10x70
+#defineTARGET_ADDR20x72
  
  static void *find_section(struct bdb_header *bdb, int section_id)

  {
@@ -357,10 +357,10 @@ parse_sdvo_device_mapping(struct drm_psb_private 
*dev_priv,
/* skip the device block if device type is invalid */
continue;
}
-   if (p_child->slave_addr != SLAVE_ADDR1 &&
-   p_child->slave_addr != SLAVE_ADDR2) {
+   if (p_child->target_addr != TARGET_ADDR1 &&
+   p_child->target_addr != TARGET_ADDR2) {
/*
-* If the slave address is neither 0x70 nor 0x72,
+* If the target address is neither 0x70 nor 0x72,
 * it is not a SDVO device. Skip it.
 */
continue;
@@ -371,22 +371,22 @@ parse_sdvo_device_mapping(struct drm_psb_private 
*dev_priv,
DRM_DEBUG_KMS("Incorrect SDVO port. Skip it\n");
continue;
}
-   DRM_DEBUG_KMS("the SDVO device with slave addr %2x is found on"
+   DRM_DEBUG_KMS("the SDVO device with target addr %2x is found on"
" %s port\n",
-   p_child->slave_addr,
+   p_child->target_addr,
(p_child->dvo_port == DEVICE_PORT_DVOB) ?
"SDVOB" : "SDVOC");
p_mapping = &(dev_priv->sdvo_mappings[p_child->dvo_port - 1]);
if (!p_mapping->initialized) {
p_mapping->dvo_port = p_child->dvo_port;
-   p_mapping->slave_addr = p_child->slave_addr;
+   p_mapping->target_addr = p_child->target_addr;
p_mapping->dvo_wiring = p_child->dvo_wiring;
p_mapping->ddc_pin = p_child->ddc_pin;
p_mapping->i2c_pin = p_child->i2c_pin;
p_mapping->initialized = 1;
DRM_DEBUG_KMS("SDVO device: dvo=%x, addr=%x, wiring=%d, 
ddc_pin=%d, i2c_pin=%d\n",
  p_mapping->dvo_port,
- p_mapping->slave_addr,
+ p_mapping->target_addr,
  p_mapping->dvo_wiring,
  p_mapping->ddc_pin,
  p_mapping->i2c_pin);
@@ -394,10 +394,10 @@ parse_sdvo_device_mapping(struct drm_psb_private 
*dev_priv,
DRM_DEBUG_KMS("Maybe one SDVO po

Re: [PATCH] drm/fb_dma: Add checks in drm_fb_dma_get_scanout_buffer()

2024-04-29 Thread Thomas Zimmermann




Am 26.04.24 um 14:10 schrieb Jocelyn Falempe:

plane->state and plane->state->fb can be NULL, so add a check before
dereferencing them.
Found by testing with the imx driver.

Fixes: 879b3b6511fe9 ("drm/fb_dma: Add generic get_scanout_buffer() for 
drm_panic")
Signed-off-by: Jocelyn Falempe 
---
  drivers/gpu/drm/drm_fb_dma_helper.c | 3 +++
  1 file changed, 3 insertions(+)

diff --git a/drivers/gpu/drm/drm_fb_dma_helper.c 
b/drivers/gpu/drm/drm_fb_dma_helper.c
index 96e5ab960f12..d7bffde94cc5 100644
--- a/drivers/gpu/drm/drm_fb_dma_helper.c
+++ b/drivers/gpu/drm/drm_fb_dma_helper.c
@@ -167,6 +167,9 @@ int drm_fb_dma_get_scanout_buffer(struct drm_plane *plane,
struct drm_gem_dma_object *dma_obj;
struct drm_framebuffer *fb;
  
+	if (!plane->state || !plane->state->fb)

+   return -ENODEV;
+


It's EINVAL here. With that fixed, free free to add

Reviewed-by: Thomas Zimmermann 

Best regards
Thomas


fb = plane->state->fb;
/* Only support linear modifier */
if (fb->modifier != DRM_FORMAT_MOD_LINEAR)

base-commit: 2e3f08a1ac99cb9a19a5cb151593d4f9df5cc6a7


--
--
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: After suspend/resume cycle ASPEED VGA monitor suffers with "No Signal" state.

2024-04-29 Thread Thomas Zimmermann

Hi

Am 23.04.24 um 21:51 schrieb Cary Garrett:

Hello,

An Aspeed VGA monitor, in my case AST 2400, after a suspend/resume
cycle suffers with a "No Signal" state. This is also true of a
IPMI/BMC remote console. To restore the "Signal" state requires
a reboot or the following workaround.

To restore the "Signal" state without rebooting issue the
following commands from a SSH session or serial console
after every suspend/resume cycle:

   sudo modprobe -r ast
   sudo modprobe ast
   
This a home media server which is updated infrequently, so

I am unable offer any guidance as to when this issue started
occurring.


Just to clarify, suspend/resume did restore the display in earlier versions?

Best regards
Thomas



Regards, Cary Garrett



Current environment:

uname -a:
Linux xx-server 6.8.7-arch1-1 #1 SMP PREEMPT_DYNAMIC Wed, 17 Apr 2024 
15:20:28 + x86_64
GNU/Linux

modinfo:
filename:   /lib/modules/6.8.7-arch1-1/kernel/drivers/gpu/drm/ast/ast.ko.zst
license:GPL and additional rights
description:AST
author: Dave Airlie
firmware:   ast_dp501_fw.bin
srcversion: 7E39455BCA2D11E968D8B2B
alias:  pci:v1A03d2010sv*sd*bc03sc*i*
alias:  pci:v1A03d2000sv*sd*bc03sc*i*
depends:i2c-algo-bit
retpoline:  Y
intree: Y
name:   ast
vermagic:   6.8.7-arch1-1 SMP preempt mod_unload
sig_id: PKCS#7
signer: Build time autogenerated kernel key
sig_key:76:06:C7:84:BC:2F:C6:38:38:61:C1:6F:32:D5:6A:03:88:22:68:1C
sig_hashalgo:   sha512
signature:  30:66:02:31:00:AD:83:EB:D2:9B:91:E6:C3:9B:52:89:51:4B:BB:06:
DE:D7:44:A6:6B:07:92:AA:75:2A:0B:20:26:73:58:09:DF:C3:86:C6:
FC:B7:D4:13:5F:5D:35:4D:67:89:73:0E:C2:02:31:00:C3:98:99:67:
B4:74:02:5C:6D:D3:81:13:D4:9F:B4:F4:CF:37:8A:7C:84:8C:73:BF:
DF:4D:D5:34:B0:0A:CE:0E:59:67:28:98:07:BF:D7:FA:68:B3:37:43:
02:1C:59:3E
parm:   modeset:Disable/Enable modesetting (int)

lspci:
04:00.0 VGA compatible controller: ASPEED Technology, Inc. ASPEED Graphics 
Family (rev 30) (prog-if
00 [VGA controller])
DeviceName: Onboard VGA
Subsystem: Super Micro Computer Inc Device 0804
Control: I/O+ Mem+ BusMaster- SpecCycle- MemWINV- VGASnoop- ParErr- 
Stepping- SERR-
FastB2B- DisINTx-
Status: Cap+ 66MHz- UDF- FastB2B- ParErr- DEVSEL=medium >TAbort- SERR-


--
--
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)



[PULL] drm-misc-fixes

2024-04-25 Thread Thomas Zimmermann
Hi Dave, Sima,

here's the PR for drm-misc-fixes.

Best regards
Thomas

drm-misc-fixes-2024-04-25:
Short summary of fixes pull:

atomic-helpers:
- Fix memory leak in drm_format_conv_state_copy()

fbdev:
- fbdefio: Fix address calculation

gma500:
- Fix crash during boot
The following changes since commit 941c0bdbc176df825adf77052263b2d63db6fef7:

  drm/panel: novatek-nt36682e: don't unregister DSI device (2024-04-16 23:17:59 
+0300)

are available in the Git repository at:

  https://gitlab.freedesktop.org/drm/misc/kernel.git 
tags/drm-misc-fixes-2024-04-25

for you to fetch changes up to 78d9161d2bcd442d93d917339297ffa057dbee8c:

  fbdev: fix incorrect address computation in deferred IO (2024-04-24 15:03:37 
+0200)


Short summary of fixes pull:

atomic-helpers:
- Fix memory leak in drm_format_conv_state_copy()

fbdev:
- fbdefio: Fix address calculation

gma500:
- Fix crash during boot


Lucas Stach (1):
  drm/atomic-helper: fix parameter order in drm_format_conv_state_copy() 
call

Nam Cao (1):
  fbdev: fix incorrect address computation in deferred IO

Patrik Jakobsson (1):
  drm/gma500: Remove lid code

 drivers/gpu/drm/drm_gem_atomic_helper.c |  4 +-
 drivers/gpu/drm/gma500/Makefile |  1 -
 drivers/gpu/drm/gma500/psb_device.c |  5 +--
 drivers/gpu/drm/gma500/psb_drv.h|  9 
 drivers/gpu/drm/gma500/psb_lid.c| 80 -
 drivers/video/fbdev/core/fb_defio.c |  2 +-
 6 files changed, 4 insertions(+), 97 deletions(-)
 delete mode 100644 drivers/gpu/drm/gma500/psb_lid.c

-- 
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 v8 6/6] drm/{i915,xe}: Implement fbdev emulation as in-kernel client

2024-04-23 Thread Thomas Zimmermann

Hi

Am 23.04.24 um 13:36 schrieb Hogander, Jouni:

On Tue, 2024-04-23 at 13:13 +0200, Thomas Zimmermann wrote:

Hi

Am 22.04.24 um 16:11 schrieb Hogander, Jouni:

On Tue, 2024-04-09 at 10:04 +0200, Thomas Zimmermann wrote:

Replace all code that initializes or releases fbdev emulation
throughout the driver. Instead initialize the fbdev client by a
single call to intel_fbdev_setup() after i915 has registered its
DRM device. Just like similar code in other drivers, i915 fbdev
emulation now acts like a regular DRM client. Do the same for xe.

The fbdev client setup consists of the initial preparation and
the
hot-plugging of the display. The latter creates the fbdev device
and sets up the fbdev framebuffer. The setup performs display
hot-plugging once. If no display can be detected, DRM probe
helpers
re-run the detection on each hotplug event.

A call to drm_client_dev_unregister() releases all in-kernel
clients
automatically. No further action is required within i915. If the
fbdev
framebuffer has been fully set up, struct fb_ops.fb_destroy
implements
the release. For partially initialized emulation, the fbdev
client
reverts the initial setup. Do the same for xe and remove its call
to
intel_fbdev_fini().

v8:
- setup client in intel_display_driver_register (Jouni)
- mention xe in commit message

v7:
- update xe driver
- reword commit message

v6:
- use 'i915' for i915 device (Jouni)
- remove unnecessary code for non-atomic mode setting (Jouni,
Ville)
- fix function name in commit message (Jouni)

v3:
-  as before, silently ignore devices without displays

v2:
-  let drm_client_register() handle initial hotplug
-  fix driver name in error message (Jani)
-  fix non-fbdev build (kernel test robot)

Signed-off-by: Thomas Zimmermann 

Reviewed-by: Jouni Högander 

Thank you so much. All patches has R-bs. Can you add the series to
the
intel tree?

Is it ok to merge patch 01/06 via intel tree as well?


Sure, np.

Best regards
Thomas



Rodrigo, This set is containing Xe display changes as well. Is it ok to
push this via drm-intel?

BR,

Jouni Högander


Best regards
Thomas


---
   drivers/gpu/drm/i915/display/intel_display.c  |   1 -
   .../drm/i915/display/intel_display_driver.c   |  20 +-
   drivers/gpu/drm/i915/display/intel_fbdev.c    | 177 ---
-
--
   drivers/gpu/drm/i915/display/intel_fbdev.h    |  20 +-
   drivers/gpu/drm/xe/display/xe_display.c   |   2 -
   5 files changed, 80 insertions(+), 140 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c
b/drivers/gpu/drm/i915/display/intel_display.c
index 614e60420a29a..161a5aabf6746 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -85,7 +85,6 @@
   #include "intel_dvo.h"
   #include "intel_fb.h"
   #include "intel_fbc.h"
-#include "intel_fbdev.h"
   #include "intel_fdi.h"
   #include "intel_fifo_underrun.h"
   #include "intel_frontbuffer.h"
diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c
b/drivers/gpu/drm/i915/display/intel_display_driver.c
index e5f052d4ff1cc..ed8589fa35448 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -514,10 +514,6 @@ int intel_display_driver_probe(struct
drm_i915_private *i915)
   
  intel_overlay_setup(i915);
   
-   ret = intel_fbdev_init(>drm);

-   if (ret)
-   return ret;
-
  /* Only enable hotplug handling once the fbdev is fully
set
up. */
  intel_hpd_init(i915);
   
@@ -544,16 +540,6 @@ void intel_display_driver_register(struct

drm_i915_private *i915)
   
  intel_display_debugfs_register(i915);
   
-   /*

-    * Some ports require correctly set-up hpd registers for
-    * detection to work properly (leading to ghost connected
-    * connector status), e.g. VGA on gm45.  Hence we can
only
set
-    * up the initial fbdev config after hpd irqs are fully
-    * enabled. We do it last so that the async config cannot
run
-    * before the connectors are registered.
-    */
-   intel_fbdev_initial_config_async(i915);
-
  /*
   * We need to coordinate the hotplugs with the
asynchronous
   * fbdev configuration, for which we use the
@@ -562,6 +548,8 @@ void intel_display_driver_register(struct
drm_i915_private *i915)
  drm_kms_helper_poll_init(>drm);
  intel_hpd_poll_disable(i915);
   
+   intel_fbdev_setup(i915);

+
  intel_display_device_info_print(DISPLAY_INFO(i915),
  DISPLAY_RUNTIME_INFO(i91
5),
);
   }
@@ -597,9 +585,6 @@ void intel_display_driver_remove_noirq(struct
drm_i915_private *i915)
   */
  intel_hpd_poll_fini(i915);
   
-   /* poll work can call into fbdev, hence clean that up

afterwards */
-   intel_fbdev_fini(i915);
-
  intel_unregister_dsm_handl

Re: [PATCH v2] fbdev: fix incorrect address computation in deferred IO

2024-04-23 Thread Thomas Zimmermann

Hi

Am 23.04.24 um 13:50 schrieb Nam Cao:

With deferred IO enabled, a page fault happens when data is written to the
framebuffer device. Then driver determines which page is being updated by
calculating the offset of the written virtual address within the virtual
memory area, and uses this offset to get the updated page within the
internal buffer. This page is later copied to hardware (thus the name
"deferred IO").

This offset calculation is only correct if the virtual memory area is
mapped to the beginning of the internal buffer. Otherwise this is wrong.
For example, if users do:
 mmap(ptr, 4096, PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0xff000);

Then the virtual memory area will mapped at offset 0xff000 within the
internal buffer. This offset 0xff000 is not accounted for, and wrong page
is updated.

Correct the calculation by using vmf->pgoff instead. With this change, the
variable "offset" will no longer hold the exact offset value, but it is
rounded down to multiples of PAGE_SIZE. But this is still correct, because
this variable is only used to calculate the page offset.

Reported-by: Harshit Mogalapalli 
Closes: 
https://lore.kernel.org/linux-fbdev/271372d6-e665-4e7f-b088-dee5f4ab3...@oracle.com
Fixes: 56c134f7f1b5 ("fbdev: Track deferred-I/O pages in pageref struct")
Cc: 
Signed-off-by: Nam Cao 


Reviewed-by: Thomas Zimmermann 

Thank you so much. I'll take care of merging the patch later this week.

Best regards
Thomas


---
v2:
   - simplify the patch by using vfg->pgoff
   - remove tested-by tag, as the patch is now different

  drivers/video/fbdev/core/fb_defio.c | 2 +-
  1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fb_defio.c 
b/drivers/video/fbdev/core/fb_defio.c
index 1ae1d35a5942..b9607d5a370d 100644
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -196,7 +196,7 @@ static vm_fault_t fb_deferred_io_track_page(struct fb_info 
*info, unsigned long
   */
  static vm_fault_t fb_deferred_io_page_mkwrite(struct fb_info *info, struct 
vm_fault *vmf)
  {
-   unsigned long offset = vmf->address - vmf->vma->vm_start;
+   unsigned long offset = vmf->pgoff << PAGE_SHIFT;
struct page *page = vmf->page;
  
  	file_update_time(vmf->vma->vm_file);


--
--
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] fbdev: fix incorrect address computation in deferred IO

2024-04-23 Thread Thomas Zimmermann

Hi

Am 23.04.24 um 11:55 schrieb Nam Cao:
[...]

Fix this by taking the mapping offset into account.

Reported-and-tested-by: Harshit Mogalapalli 
Closes: 
https://lore.kernel.org/linux-fbdev/271372d6-e665-4e7f-b088-dee5f4ab3...@oracle.com
Fixes: 56c134f7f1b5 ("fbdev: Track deferred-I/O pages in pageref struct")
Cc: sta...@vger.kernel.org
Signed-off-by: Nam Cao 
---
   drivers/video/fbdev/core/fb_defio.c | 3 ++-
   1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fb_defio.c 
b/drivers/video/fbdev/core/fb_defio.c
index dae96c9f61cf..d5d6cd9e8b29 100644
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -196,7 +196,8 @@ static vm_fault_t fb_deferred_io_track_page(struct fb_info 
*info, unsigned long
*/
   static vm_fault_t fb_deferred_io_page_mkwrite(struct fb_info *info, struct 
vm_fault *vmf)
   {
-   unsigned long offset = vmf->address - vmf->vma->vm_start;
+   unsigned long offset = vmf->address - vmf->vma->vm_start
+   + (vmf->vma->vm_pgoff << PAGE_SHIFT);

The page-fault handler at [1] use vm_fault.pgoff to retrieve the page
structure. Can we do the same here and avoid that computation?

Yes, thanks for the suggestion.

It will change things a bit: offset will not be the exact value anymore,
but will be rounded down to multiple of PAGE_SIZE. But that doesn't matter,
because it will only be used to calculate the page offset later on.

We can clean this up and rename this "offset" to "pg_offset". But that's
for another day.


But can't we use struct vm_fault.pgoff directly? The page-fault handler 
has used it since forever. The look-up code for the pageref should 
probably do the same, because there's a 1:1 connection between the page 
and the pageref. The pageref structure only exists because we cannot 
store its data in struct page directly.


AFAICT pgoff is exactly the value want to compute. See [1] and  the 
calculation at [2].


[1] https://elixir.bootlin.com/linux/v6.8/source/mm/memory.c#L5222
[2] 
https://elixir.bootlin.com/linux/v6.8/source/include/linux/pagemap.h#L957


Best regards
Thomas



Best regards,
Nam


--
--
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 v8 6/6] drm/{i915,xe}: Implement fbdev emulation as in-kernel client

2024-04-23 Thread Thomas Zimmermann

Hi

Am 22.04.24 um 16:11 schrieb Hogander, Jouni:

On Tue, 2024-04-09 at 10:04 +0200, Thomas Zimmermann wrote:

Replace all code that initializes or releases fbdev emulation
throughout the driver. Instead initialize the fbdev client by a
single call to intel_fbdev_setup() after i915 has registered its
DRM device. Just like similar code in other drivers, i915 fbdev
emulation now acts like a regular DRM client. Do the same for xe.

The fbdev client setup consists of the initial preparation and the
hot-plugging of the display. The latter creates the fbdev device
and sets up the fbdev framebuffer. The setup performs display
hot-plugging once. If no display can be detected, DRM probe helpers
re-run the detection on each hotplug event.

A call to drm_client_dev_unregister() releases all in-kernel clients
automatically. No further action is required within i915. If the
fbdev
framebuffer has been fully set up, struct fb_ops.fb_destroy
implements
the release. For partially initialized emulation, the fbdev client
reverts the initial setup. Do the same for xe and remove its call to
intel_fbdev_fini().

v8:
- setup client in intel_display_driver_register (Jouni)
- mention xe in commit message

v7:
- update xe driver
- reword commit message

v6:
- use 'i915' for i915 device (Jouni)
- remove unnecessary code for non-atomic mode setting (Jouni, Ville)
- fix function name in commit message (Jouni)

v3:
-  as before, silently ignore devices without displays

v2:
-  let drm_client_register() handle initial hotplug
-  fix driver name in error message (Jani)
-  fix non-fbdev build (kernel test robot)

Signed-off-by: Thomas Zimmermann 

Reviewed-by: Jouni Högander 


Thank you so much. All patches has R-bs. Can you add the series to the 
intel tree?


Best regards
Thomas




---
  drivers/gpu/drm/i915/display/intel_display.c  |   1 -
  .../drm/i915/display/intel_display_driver.c   |  20 +-
  drivers/gpu/drm/i915/display/intel_fbdev.c    | 177 
--
  drivers/gpu/drm/i915/display/intel_fbdev.h    |  20 +-
  drivers/gpu/drm/xe/display/xe_display.c   |   2 -
  5 files changed, 80 insertions(+), 140 deletions(-)

diff --git a/drivers/gpu/drm/i915/display/intel_display.c
b/drivers/gpu/drm/i915/display/intel_display.c
index 614e60420a29a..161a5aabf6746 100644
--- a/drivers/gpu/drm/i915/display/intel_display.c
+++ b/drivers/gpu/drm/i915/display/intel_display.c
@@ -85,7 +85,6 @@
  #include "intel_dvo.h"
  #include "intel_fb.h"
  #include "intel_fbc.h"
-#include "intel_fbdev.h"
  #include "intel_fdi.h"
  #include "intel_fifo_underrun.h"
  #include "intel_frontbuffer.h"
diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c
b/drivers/gpu/drm/i915/display/intel_display_driver.c
index e5f052d4ff1cc..ed8589fa35448 100644
--- a/drivers/gpu/drm/i915/display/intel_display_driver.c
+++ b/drivers/gpu/drm/i915/display/intel_display_driver.c
@@ -514,10 +514,6 @@ int intel_display_driver_probe(struct
drm_i915_private *i915)
  
 intel_overlay_setup(i915);
  
-   ret = intel_fbdev_init(>drm);

-   if (ret)
-   return ret;
-
 /* Only enable hotplug handling once the fbdev is fully set
up. */
 intel_hpd_init(i915);
  
@@ -544,16 +540,6 @@ void intel_display_driver_register(struct

drm_i915_private *i915)
  
 intel_display_debugfs_register(i915);
  
-   /*

-    * Some ports require correctly set-up hpd registers for
-    * detection to work properly (leading to ghost connected
-    * connector status), e.g. VGA on gm45.  Hence we can only
set
-    * up the initial fbdev config after hpd irqs are fully
-    * enabled. We do it last so that the async config cannot run
-    * before the connectors are registered.
-    */
-   intel_fbdev_initial_config_async(i915);
-
 /*
  * We need to coordinate the hotplugs with the asynchronous
  * fbdev configuration, for which we use the
@@ -562,6 +548,8 @@ void intel_display_driver_register(struct
drm_i915_private *i915)
 drm_kms_helper_poll_init(>drm);
 intel_hpd_poll_disable(i915);
  
+   intel_fbdev_setup(i915);

+
 intel_display_device_info_print(DISPLAY_INFO(i915),
 DISPLAY_RUNTIME_INFO(i915),
);
  }
@@ -597,9 +585,6 @@ void intel_display_driver_remove_noirq(struct
drm_i915_private *i915)
  */
 intel_hpd_poll_fini(i915);
  
-   /* poll work can call into fbdev, hence clean that up

afterwards */
-   intel_fbdev_fini(i915);
-
 intel_unregister_dsm_handler();
  
 /* flush any delayed tasks or pending work */

@@ -640,7 +625,6 @@ void intel_display_driver_unregister(struct
drm_i915_private *i915)
  
 drm_client_dev_unregister(>drm);
  
-   intel_fbdev_unregister(i915);

 /*
  * After flushing the fbdev (incl. a late async config which
  * will have de

Re: [PATCH] fbdev: fix incorrect address computation in deferred IO

2024-04-23 Thread Thomas Zimmermann

Hi,

thanks for following through with the bug and sending the patch

Am 19.04.24 um 21:00 schrieb Nam Cao:

With deferred IO enabled, a page fault happens when data is written to the
framebuffer device. Then driver determines which page is being updated by
calculating the offset of the written virtual address within the virtual
memory area, and uses this offset to get the updated page within the
internal buffer. This page is later copied to hardware (thus the name
"deferred IO").

This calculation is only correct if the virtual memory area is mapped to
the beginning of the internal buffer. Otherwise this is wrong. For example,
if users do:
 mmap(ptr, 4096, PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0xff000);

Then the virtual memory area will mapped at offset 0xff000 within the
internal buffer. This offset 0xff000 is not accounted for, and wrong page
is updated. This will lead to wrong pixels being updated on the device.

However, it gets worse: if users do 2 mmap to the same virtual address, for
example:

 int fd = open("/dev/fb0", O_RDWR, 0);
 char *ptr = (char *) 0x2000ul;
 mmap(ptr, 4096, PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0xff000);
 *ptr = 0; // write #1
 mmap(ptr, 4096, PROT_WRITE, MAP_FIXED | MAP_SHARED, fd, 0);
 *ptr = 0; // write #2

In this case, both write #1 and write #2 apply to the same virtual address
(0x2000ul), and the driver mistakenly thinks the same page is being
written to. When the second write happens, the driver thinks this is the
same page as the last time, and reuse the page from write #1. The driver
then lock_page() an incorrect page, and returns VM_FAULT_LOCKED with the
correct page unlocked. It is unclear what will happen with memory
management subsystem after that, but likely something terrible.


Please tone down the drama. :)



Fix this by taking the mapping offset into account.

Reported-and-tested-by: Harshit Mogalapalli 
Closes: 
https://lore.kernel.org/linux-fbdev/271372d6-e665-4e7f-b088-dee5f4ab3...@oracle.com
Fixes: 56c134f7f1b5 ("fbdev: Track deferred-I/O pages in pageref struct")
Cc: sta...@vger.kernel.org
Signed-off-by: Nam Cao 
---
  drivers/video/fbdev/core/fb_defio.c | 3 ++-
  1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/drivers/video/fbdev/core/fb_defio.c 
b/drivers/video/fbdev/core/fb_defio.c
index dae96c9f61cf..d5d6cd9e8b29 100644
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -196,7 +196,8 @@ static vm_fault_t fb_deferred_io_track_page(struct fb_info 
*info, unsigned long
   */
  static vm_fault_t fb_deferred_io_page_mkwrite(struct fb_info *info, struct 
vm_fault *vmf)
  {
-   unsigned long offset = vmf->address - vmf->vma->vm_start;
+   unsigned long offset = vmf->address - vmf->vma->vm_start
+   + (vmf->vma->vm_pgoff << PAGE_SHIFT);


The page-fault handler at [1] use vm_fault.pgoff to retrieve the page 
structure. Can we do the same here and avoid that computation?


Best regards
Thomas

[1] 
https://elixir.bootlin.com/linux/v6.8/source/drivers/video/fbdev/core/fb_defio.c#L100



struct page *page = vmf->page;
  
  	file_update_time(vmf->vma->vm_file);


--
--
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] drm/atomic-helper: fix parameter order in drm_format_conv_state_copy() call

2024-04-19 Thread Thomas Zimmermann

Hi,

thanks for this fix.

Am 04.04.24 um 10:17 schrieb Lucas Stach:

Old and new state parameters are swapped, so the old state was cleared
instead of the new duplicated state.

Fixes: 903674588a48 ("drm/atomic-helper: Add format-conversion state to shadow-plane 
state")
Signed-off-by: Lucas Stach 
Tested-by: Leonard Göhrs 


Reviewed-by: Thomas Zimmermann 

Please also add

Cc:  # v6.8+

Best regards
Thomas


---
  drivers/gpu/drm/drm_gem_atomic_helper.c | 4 ++--
  1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/drm_gem_atomic_helper.c 
b/drivers/gpu/drm/drm_gem_atomic_helper.c
index e440f458b663..93337543aac3 100644
--- a/drivers/gpu/drm/drm_gem_atomic_helper.c
+++ b/drivers/gpu/drm/drm_gem_atomic_helper.c
@@ -224,8 +224,8 @@ __drm_gem_duplicate_shadow_plane_state(struct drm_plane 
*plane,
  
  	__drm_atomic_helper_plane_duplicate_state(plane, _shadow_plane_state->base);
  
-	drm_format_conv_state_copy(_plane_state->fmtcnv_state,

-  _shadow_plane_state->fmtcnv_state);
+   drm_format_conv_state_copy(_shadow_plane_state->fmtcnv_state,
+  _plane_state->fmtcnv_state);
  }
  EXPORT_SYMBOL(__drm_gem_duplicate_shadow_plane_state);
  


--
--
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)



[PATCH v3 25/43] drm/ingenic: Use fbdev-dma

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports
damage handling, which is required by ingenic. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: Paul Cercueil 
Acked-by: Paul Cercueil 
---
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c 
b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
index 0751235007a7e..39fa291f43dd1 100644
--- a/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
+++ b/drivers/gpu/drm/ingenic/ingenic-drm-drv.c
@@ -31,7 +31,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -1399,7 +1399,7 @@ static int ingenic_drm_bind(struct device *dev, bool 
has_components)
goto err_clk_notifier_unregister;
}
 
-   drm_fbdev_generic_setup(drm, 32);
+   drm_fbdev_dma_setup(drm, 32);
 
return 0;
 
-- 
2.44.0



[PATCH v3 00/43] drm: Provide fbdev emulation per memory manager

2024-04-19 Thread Thomas Zimmermann
DRM provides 3 different memory managers with slightly different
characteristics: DMA-based, SHMEM-based and TTM. This affects fbdev
emulation as each requires different handling of mmap(). This series
reworks fbdev emulation to provide an optimized emulation for each
of the memory managers.

Patch 1 fixes a minor bug in fbdev-generic.

Patches 2 to 8 implement fbdev-shmem, which is optimized for drivers
with SHMEM-based allocation. Patches 2 to 7 prepare deferred I/O to
support driver-custom page lookups. When the mmap'ed framebuffer sees
a pagefault, the deferred-I/O code can ask the graphics driver of the
page (instead of trying to detect it by itself). Using this hook,
patch 8 implements fbdev-shmem. The code is similar to fbdev-generic,
but does not require an additional shadow buffer for mmap(). Mmap'ed
pages are instead provided from the GEM buffer object. That saves a
few MiB of framebuffer memory and copying between the internal buffers.

Patches 9 to 20 convert SHMEM-based drivers to fbdev-shmem.

Patch 21 adds damage handling and deferred I/O to fbdev-dma. Such
code has been tested on the DMA-based omapdrm and can be adopted for
all drivers.

Patches 22 to 41 convert DMA-based drivers to fbdev-dma. These drivers
could not use it because of the missing support for damage handling.

Patch 42 renames fbdev-generic to fbdev-ttm. Only TTM-based drivers
still use it, so building it can be linked to TTM as well.

Patch 43 cleans up the documentation.

Tested with simpledrm, vc4 and amdgpu.

v3:
- fbdev-dma: init fb_ops with DMAMEM initializer (Javier)
- fbdev-shmem: clarify get_page usage (Javier)
v2:
- fbdev-shmem: use drm_driver_legacy_fb_format() (Geert)
- fix a few typos

Thomas Zimmermann (43):
  drm/fbdev-generic: Do not set physical framebuffer address
  fbdev/deferred-io: Move pageref setup into separate helper
  fbdev/deferred-io: Clean up pageref on lastclose
  fbdev/deferred-io: Test screen_buffer for vmalloc'ed memory
  fbdev/deferred-io: Test smem_start for I/O memory
  fbdev/deferred-io: Always call get_page() for framebuffer pages
  fbdev/deferred-io: Provide get_page hook in struct fb_deferred_io
  drm/fbdev: Add fbdev-shmem
  drm/ast: Use fbdev-shmem
  drm/gud: Use fbdev-shmem
  drm/hyperv: Use fbdev-shmem
  drm/mgag200: Use fbdev-shmem
  drm/solomon: Use fbdev-shmem
  drm/tiny/cirrus: Use fbdev-shmem
  drm/tiny/gm12u320: Use fbdev-shmem
  drm/tiny/ofdrm: Use fbdev-shmem
  drm/tiny/simpledrm: Use fbdev-shmem
  drm/udl: Use fbdev-shmem
  drm/virtio: Use fbdev-shmem
  drm/vkms: Use fbdev-shmem
  drm/fbdev-dma: Implement damage handling and deferred I/O
  drm/arm/komeda: Use fbdev-dma
  drm/hisilicon/kirin: Use fbdev-dma
  drm/imx/lcdc: Use fbdev-dma
  drm/ingenic: Use fbdev-dma
  drm/mediatek: Use fbdev-dma
  drm/panel/panel-ilitek-9341: Use fbdev-dma
  drm/renesas/rcar-du: Use fbdev-dma
  drm/renesas/rz-du: Use fbdev-dma
  drm/renesas/shmobile: Use fbdev-dma
  drm/rockchip: Use fbdev-dma
  drm/tiny/hx8357d: Use fbdev-dma
  drm/tiny/ili9163: Use fbdev-dma
  drm/tiny/ili9225: Use fbdev-dma
  drm/tiny/ili9341: Use fbdev-dma
  drm/tiny/ili9486: Use fbdev-dma
  drm/tiny/mi0283qt: Use fbdev-dma
  drm/tiny/panel-mipi-dbi: Use fbdev-dma
  drm/tiny/repaper: Use fbdev-dma
  drm/tiny/st7586: Use fbdev-dma
  drm/tiny/st7735r: Use fbdev-dma
  drm/fbdev-generic: Convert to fbdev-ttm
  drm/fbdev: Clean up fbdev documentation

 Documentation/gpu/drm-kms-helpers.rst |  12 +-
 Documentation/gpu/todo.rst|  13 -
 drivers/gpu/drm/Makefile  |   6 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |   6 +-
 .../gpu/drm/arm/display/komeda/komeda_drv.c   |   4 +-
 drivers/gpu/drm/ast/ast_drv.c |   4 +-
 drivers/gpu/drm/drm_drv.c |   2 +-
 drivers/gpu/drm/drm_fb_helper.c   |  11 +-
 drivers/gpu/drm/drm_fbdev_dma.c   |  65 +++-
 drivers/gpu/drm/drm_fbdev_shmem.c | 316 ++
 .../{drm_fbdev_generic.c => drm_fbdev_ttm.c}  |  81 +++--
 drivers/gpu/drm/gud/gud_drv.c |   4 +-
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   |   4 +-
 .../gpu/drm/hisilicon/kirin/kirin_drm_drv.c   |   4 +-
 drivers/gpu/drm/hyperv/hyperv_drm_drv.c   |   4 +-
 drivers/gpu/drm/imx/lcdc/imx-lcdc.c   |   4 +-
 drivers/gpu/drm/ingenic/ingenic-drm-drv.c |   4 +-
 drivers/gpu/drm/loongson/Kconfig  |   1 +
 drivers/gpu/drm/loongson/lsdc_drv.c   |   4 +-
 drivers/gpu/drm/mediatek/mtk_drm_drv.c|   4 +-
 drivers/gpu/drm/mgag200/mgag200_drv.c |   4 +-
 drivers/gpu/drm/nouveau/nouveau_drm.c |   6 +-
 drivers/gpu/drm/panel/panel-ilitek-ili9341.c  |   4 +-
 drivers/gpu/drm/qxl/qxl_drv.c |   4 +-
 drivers/gpu/drm/renesas/rcar-du/rcar_du_drv.c |   4 +-
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c  |   4 +-
 .../gpu/drm/renesas/shmobile/shmob_drm_drv.c  |   4 +-
 drivers/gpu/drm/rockchip/rockchip_drm_drv.c   |   4 +-
 drivers/gpu/

[PATCH v3 34/43] drm/tiny/ili9225: Use fbdev-dma

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports
damage handling, which is required by ili9225. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: David Lechner 
Acked-by: David Lechner 
---
 drivers/gpu/drm/tiny/ili9225.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tiny/ili9225.c b/drivers/gpu/drm/tiny/ili9225.c
index dd8b0a181be94..537df5f5b8a6e 100644
--- a/drivers/gpu/drm/tiny/ili9225.c
+++ b/drivers/gpu/drm/tiny/ili9225.c
@@ -20,7 +20,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -426,7 +426,7 @@ static int ili9225_probe(struct spi_device *spi)
 
spi_set_drvdata(spi, drm);
 
-   drm_fbdev_generic_setup(drm, 0);
+   drm_fbdev_dma_setup(drm, 0);
 
return 0;
 }
-- 
2.44.0



[PATCH v3 24/43] drm/imx/lcdc: Use fbdev-dma

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports
damage handling, which is required by lcdc. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: Shawn Guo 
Cc: Sascha Hauer 
Cc: Pengutronix Kernel Team 
Cc: Fabio Estevam 
Cc: NXP Linux Team 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/imx/lcdc/imx-lcdc.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c 
b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
index 43ddf3a9810b6..36668455aee8c 100644
--- a/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
+++ b/drivers/gpu/drm/imx/lcdc/imx-lcdc.c
@@ -5,7 +5,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -501,7 +501,7 @@ static int imx_lcdc_probe(struct platform_device *pdev)
if (ret)
return dev_err_probe(dev, ret, "Cannot register device\n");
 
-   drm_fbdev_generic_setup(drm, 0);
+   drm_fbdev_dma_setup(drm, 0);
 
return 0;
 }
-- 
2.44.0



[PATCH v3 17/43] drm/tiny/simpledrm: Use fbdev-shmem

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-shmem. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: Thomas Zimmermann 
Cc: Javier Martinez Canillas 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/tiny/simpledrm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tiny/simpledrm.c b/drivers/gpu/drm/tiny/simpledrm.c
index 7ce1c46176750..3cb09ad5f7537 100644
--- a/drivers/gpu/drm/tiny/simpledrm.c
+++ b/drivers/gpu/drm/tiny/simpledrm.c
@@ -17,7 +17,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -1026,7 +1026,7 @@ static int simpledrm_probe(struct platform_device *pdev)
if (color_mode == 16)
color_mode = sdev->format->depth; // can be 15 or 16
 
-   drm_fbdev_generic_setup(dev, color_mode);
+   drm_fbdev_shmem_setup(dev, color_mode);
 
return 0;
 }
-- 
2.44.0



[PATCH v3 37/43] drm/tiny/mi0283qt: Use fbdev-dma

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports
damage handling, which is required by mi0283qt. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: "Noralf Trønnes" 
Acked-by: Noralf Trønnes 
---
 drivers/gpu/drm/tiny/mi0283qt.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tiny/mi0283qt.c b/drivers/gpu/drm/tiny/mi0283qt.c
index 01ff43c8ac3ff..e46581d74c257 100644
--- a/drivers/gpu/drm/tiny/mi0283qt.c
+++ b/drivers/gpu/drm/tiny/mi0283qt.c
@@ -15,7 +15,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -226,7 +226,7 @@ static int mi0283qt_probe(struct spi_device *spi)
 
spi_set_drvdata(spi, drm);
 
-   drm_fbdev_generic_setup(drm, 0);
+   drm_fbdev_dma_setup(drm, 0);
 
return 0;
 }
-- 
2.44.0



[PATCH v3 20/43] drm/vkms: Use fbdev-shmem

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-shmem. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: Rodrigo Siqueira 
Cc: Melissa Wen 
Cc: "Maíra Canal" 
Cc: Haneen Mohammed 
Cc: Daniel Vetter 
Reviewed-by: Javier Martinez Canillas 
Acked-by: Maíra Canal 
---
 drivers/gpu/drm/vkms/vkms_drv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/vkms/vkms_drv.c b/drivers/gpu/drm/vkms/vkms_drv.c
index dd0af086e7fa9..8dc9dc13896e9 100644
--- a/drivers/gpu/drm/vkms/vkms_drv.c
+++ b/drivers/gpu/drm/vkms/vkms_drv.c
@@ -17,7 +17,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -223,7 +223,7 @@ static int vkms_create(struct vkms_config *config)
if (ret)
goto out_devres;
 
-   drm_fbdev_generic_setup(_device->drm, 0);
+   drm_fbdev_shmem_setup(_device->drm, 0);
 
return 0;
 
-- 
2.44.0



[PATCH v3 15/43] drm/tiny/gm12u320: Use fbdev-shmem

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-shmem. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: Hans de Goede 
Reviewed-by: Hans de Goede 
---
 drivers/gpu/drm/tiny/gm12u320.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tiny/gm12u320.c b/drivers/gpu/drm/tiny/gm12u320.c
index 0187539ff5eaa..8b4efd39d7c41 100644
--- a/drivers/gpu/drm/tiny/gm12u320.c
+++ b/drivers/gpu/drm/tiny/gm12u320.c
@@ -13,7 +13,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -699,7 +699,7 @@ static int gm12u320_usb_probe(struct usb_interface 
*interface,
if (ret)
goto err_put_device;
 
-   drm_fbdev_generic_setup(dev, 0);
+   drm_fbdev_shmem_setup(dev, 0);
 
return 0;
 
-- 
2.44.0



[PATCH v3 19/43] drm/virtio: Use fbdev-shmem

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-shmem. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: David Airlie 
Cc: Gerd Hoffmann 
Cc: Gurchetan Singh 
Cc: Chia-I Wu 
Tested-by: Dmitry Osipenko 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/virtio/virtgpu_drv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.c 
b/drivers/gpu/drm/virtio/virtgpu_drv.c
index 9539aa28937fa..3d626bbaab9e4 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.c
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.c
@@ -35,7 +35,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 
 #include "virtgpu_drv.h"
@@ -103,7 +103,7 @@ static int virtio_gpu_probe(struct virtio_device *vdev)
if (ret)
goto err_deinit;
 
-   drm_fbdev_generic_setup(vdev->priv, 32);
+   drm_fbdev_shmem_setup(vdev->priv, 32);
return 0;
 
 err_deinit:
-- 
2.44.0



[PATCH v3 21/43] drm/fbdev-dma: Implement damage handling and deferred I/O

2024-04-19 Thread Thomas Zimmermann
Add support for damage handling and deferred I/O to fbdev-dma. This
enables fbdev-dma to support all DMA-memory-based DRM drivers, even
such with a dirty callback in their framebuffers.

The patch adds the code for deferred I/O and also sets a dedicated
helper for struct fb_ops.fb_mmap that support coherent mappings.

v3:
- init fb_ops with FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS() (Javier)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/drm_fbdev_dma.c | 65 ++---
 1 file changed, 51 insertions(+), 14 deletions(-)

diff --git a/drivers/gpu/drm/drm_fbdev_dma.c b/drivers/gpu/drm/drm_fbdev_dma.c
index 6c9427bb4053b..5eeb5164e9e2b 100644
--- a/drivers/gpu/drm/drm_fbdev_dma.c
+++ b/drivers/gpu/drm/drm_fbdev_dma.c
@@ -4,6 +4,7 @@
 
 #include 
 #include 
+#include 
 #include 
 #include 
 #include 
@@ -35,6 +36,22 @@ static int drm_fbdev_dma_fb_release(struct fb_info *info, 
int user)
return 0;
 }
 
+FB_GEN_DEFAULT_DEFERRED_DMAMEM_OPS(drm_fbdev_dma,
+  drm_fb_helper_damage_range,
+  drm_fb_helper_damage_area);
+
+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_framebuffer *fb = fb_helper->fb;
+   struct drm_gem_dma_object *dma = drm_fb_dma_get_gem_obj(fb, 0);
+
+   if (!dma->map_noncoherent)
+   vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+   return fb_deferred_io_mmap(info, vma);
+}
+
 static void drm_fbdev_dma_fb_destroy(struct fb_info *info)
 {
struct drm_fb_helper *fb_helper = info->par;
@@ -51,20 +68,13 @@ static void drm_fbdev_dma_fb_destroy(struct fb_info *info)
kfree(fb_helper);
 }
 
-static int drm_fbdev_dma_fb_mmap(struct fb_info *info, struct vm_area_struct 
*vma)
-{
-   struct drm_fb_helper *fb_helper = info->par;
-
-   return drm_gem_prime_mmap(fb_helper->buffer->gem, vma);
-}
-
 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_DEFAULT_DMAMEM_OPS_RDWR,
+   __FB_DEFAULT_DEFERRED_OPS_RDWR(drm_fbdev_dma),
DRM_FB_HELPER_DEFAULT_OPS,
-   __FB_DEFAULT_DMAMEM_OPS_DRAW,
+   __FB_DEFAULT_DEFERRED_OPS_DRAW(drm_fbdev_dma),
.fb_mmap = drm_fbdev_dma_fb_mmap,
.fb_destroy = drm_fbdev_dma_fb_destroy,
 };
@@ -98,10 +108,6 @@ static int drm_fbdev_dma_helper_fb_probe(struct 
drm_fb_helper *fb_helper,
dma_obj = to_drm_gem_dma_obj(buffer->gem);
 
fb = buffer->fb;
-   if (drm_WARN_ON(dev, fb->funcs->dirty)) {
-   ret = -ENODEV; /* damage handling not supported; use generic 
emulation */
-   goto err_drm_client_buffer_delete;
-   }
 
ret = drm_client_buffer_vmap(buffer, );
if (ret) {
@@ -112,7 +118,7 @@ static int drm_fbdev_dma_helper_fb_probe(struct 
drm_fb_helper *fb_helper,
}
 
fb_helper->buffer = buffer;
-   fb_helper->fb = buffer->fb;
+   fb_helper->fb = fb;
 
info = drm_fb_helper_alloc_info(fb_helper);
if (IS_ERR(info)) {
@@ -133,8 +139,19 @@ static int drm_fbdev_dma_helper_fb_probe(struct 
drm_fb_helper *fb_helper,
info->fix.smem_start = page_to_phys(virt_to_page(info->screen_buffer));
info->fix.smem_len = info->screen_size;
 
+   /* deferred I/O */
+   fb_helper->fbdefio.delay = HZ / 20;
+   fb_helper->fbdefio.deferred_io = drm_fb_helper_deferred_io;
+
+   info->fbdefio = _helper->fbdefio;
+   ret = fb_deferred_io_init(info);
+   if (ret)
+   goto err_drm_fb_helper_release_info;
+
return 0;
 
+err_drm_fb_helper_release_info:
+   drm_fb_helper_release_info(fb_helper);
 err_drm_client_buffer_vunmap:
fb_helper->fb = NULL;
fb_helper->buffer = NULL;
@@ -144,8 +161,28 @@ static int drm_fbdev_dma_helper_fb_probe(struct 
drm_fb_helper *fb_helper,
return ret;
 }
 
+static int drm_fbdev_dma_helper_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 drm_fbdev_dma_helper_funcs = {
.fb_probe = drm_fbdev_dma_helper_fb_probe,
+   .fb_dirty = drm_fbdev_dma_helper_fb_dirty,
 };
 
 /*
-- 
2.44.0



[PATCH v3 33/43] drm/tiny/ili9163: Use fbdev-dma

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports
damage handling, which is required by ili9163. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/tiny/ili9163.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tiny/ili9163.c b/drivers/gpu/drm/tiny/ili9163.c
index bc4384d410fcc..86f9d88349015 100644
--- a/drivers/gpu/drm/tiny/ili9163.c
+++ b/drivers/gpu/drm/tiny/ili9163.c
@@ -9,7 +9,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -185,7 +185,7 @@ static int ili9163_probe(struct spi_device *spi)
if (ret)
return ret;
 
-   drm_fbdev_generic_setup(drm, 0);
+   drm_fbdev_dma_setup(drm, 0);
 
return 0;
 }
-- 
2.44.0



[PATCH v3 41/43] drm/tiny/st7735r: Use fbdev-dma

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports
damage handling, which is required by st7735r. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: David Lechner 
Acked-by: David Lechner 
---
 drivers/gpu/drm/tiny/st7735r.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tiny/st7735r.c b/drivers/gpu/drm/tiny/st7735r.c
index 477eb36fbb70d..1676da00883d3 100644
--- a/drivers/gpu/drm/tiny/st7735r.c
+++ b/drivers/gpu/drm/tiny/st7735r.c
@@ -18,7 +18,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -241,7 +241,7 @@ static int st7735r_probe(struct spi_device *spi)
 
spi_set_drvdata(spi, drm);
 
-   drm_fbdev_generic_setup(drm, 0);
+   drm_fbdev_dma_setup(drm, 0);
 
return 0;
 }
-- 
2.44.0



[PATCH v3 43/43] drm/fbdev: Clean up fbdev documentation

2024-04-19 Thread Thomas Zimmermann
Rewrite some docs that are not up-to-date any longer. Remove the TODO
item for fbdev-generic conversion, as the helper has been replaced. Make
documentation for DMA, SHMEM and TTM emulation available.

Signed-off-by: Thomas Zimmermann 
Cc: Jonathan Corbet 
Reviewed-by: Javier Martinez Canillas 
---
 Documentation/gpu/drm-kms-helpers.rst | 12 +---
 Documentation/gpu/todo.rst| 13 -
 drivers/gpu/drm/drm_drv.c |  2 +-
 drivers/gpu/drm/drm_fb_helper.c   | 11 ++-
 include/drm/drm_mode_config.h |  4 ++--
 5 files changed, 14 insertions(+), 28 deletions(-)

diff --git a/Documentation/gpu/drm-kms-helpers.rst 
b/Documentation/gpu/drm-kms-helpers.rst
index e46ab9b670acd..8435e8621cc08 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -110,15 +110,21 @@ fbdev Helper Functions Reference
 .. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c
:doc: fbdev helpers
 
-.. kernel-doc:: include/drm/drm_fb_helper.h
-   :internal:
+.. kernel-doc:: drivers/gpu/drm/drm_fbdev_dma.c
+   :export:
 
-.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c
+.. kernel-doc:: drivers/gpu/drm/drm_fbdev_shmem.c
:export:
 
 .. kernel-doc:: drivers/gpu/drm/drm_fbdev_ttm.c
:export:
 
+.. kernel-doc:: include/drm/drm_fb_helper.h
+   :internal:
+
+.. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c
+   :export:
+
 format Helper Functions Reference
 =
 
diff --git a/Documentation/gpu/todo.rst b/Documentation/gpu/todo.rst
index fb9ad120b1414..e2a0585915b32 100644
--- a/Documentation/gpu/todo.rst
+++ b/Documentation/gpu/todo.rst
@@ -243,19 +243,6 @@ Contact: Maintainer of the driver you plan to convert
 
 Level: Intermediate
 
-Convert drivers to use drm_fbdev_generic_setup()
-
-
-Most drivers can use drm_fbdev_generic_setup(). Driver have to implement
-atomic modesetting and GEM vmap support. Historically, generic fbdev emulation
-expected the framebuffer in system memory or system-like memory. By employing
-struct iosys_map, drivers with frambuffers in I/O memory can be supported
-as well.
-
-Contact: Maintainer of the driver you plan to convert
-
-Level: Intermediate
-
 Reimplement functions in drm_fbdev_fb_ops without fbdev
 ---
 
diff --git a/drivers/gpu/drm/drm_drv.c b/drivers/gpu/drm/drm_drv.c
index 243cacb3575c0..cfcd45480d326 100644
--- a/drivers/gpu/drm/drm_drv.c
+++ b/drivers/gpu/drm/drm_drv.c
@@ -345,7 +345,7 @@ void drm_minor_release(struct drm_minor *minor)
  * if (ret)
  * return ret;
  *
- * drm_fbdev_generic_setup(drm, 32);
+ * drm_fbdev_{...}_setup(drm, 32);
  *
  * return 0;
  * }
diff --git a/drivers/gpu/drm/drm_fb_helper.c b/drivers/gpu/drm/drm_fb_helper.c
index d612133e2cf7e..e2e19f49342e1 100644
--- a/drivers/gpu/drm/drm_fb_helper.c
+++ b/drivers/gpu/drm/drm_fb_helper.c
@@ -85,12 +85,8 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
  * The fb helper functions are useful to provide an fbdev on top of a drm 
kernel
  * mode setting driver. They can be used mostly independently from the crtc
  * helper functions used by many drivers to implement the kernel mode setting
- * interfaces.
- *
- * Drivers that support a dumb buffer with a virtual address and mmap support,
- * should try out the generic fbdev emulation using drm_fbdev_generic_setup().
- * It will automatically set up deferred I/O if the driver requires a shadow
- * buffer.
+ * interfaces. Drivers that use one of the shared memory managers, TTM, SHMEM,
+ * DMA, should instead use the corresponding fbdev emulation.
  *
  * Existing fbdev implementations should restore the fbdev console by using
  * drm_fb_helper_lastclose() as their _driver.lastclose callback.
@@ -126,9 +122,6 @@ static DEFINE_MUTEX(kernel_fb_helper_lock);
  * atomic context. If drm_fb_helper_deferred_io() is used as the deferred_io
  * callback it will also schedule dirty_work with the damage collected from the
  * mmap page writes.
- *
- * Deferred I/O is not compatible with SHMEM. Such drivers should request an
- * fbdev shadow buffer and call drm_fbdev_generic_setup() instead.
  */
 
 static void drm_fb_helper_restore_lut_atomic(struct drm_crtc *crtc)
diff --git a/include/drm/drm_mode_config.h b/include/drm/drm_mode_config.h
index 9d8acf7a10eb8..77b8429e7b2b2 100644
--- a/include/drm/drm_mode_config.h
+++ b/include/drm/drm_mode_config.h
@@ -106,8 +106,8 @@ struct drm_mode_config_funcs {
 * Drivers implementing fbdev emulation use 
drm_kms_helper_hotplug_event()
 * to call this hook to inform the fbdev helper of output changes.
 *
-* This hook is deprecated, drivers should instead use
-* drm_fbdev_generic_setup() which takes care of any necessary
+* This hook is deprecated, drivers should instead implement fbdev
+* support with struct

[PATCH v3 29/43] drm/renesas/rz-du: Use fbdev-dma

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports
damage handling, which is required by rz-du. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: Biju Das 
Tested-by: Biju Das 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c 
b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
index 470d34da1d6c4..e5eca8691a331 100644
--- a/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
+++ b/drivers/gpu/drm/renesas/rz-du/rzg2l_du_drv.c
@@ -14,7 +14,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 
@@ -149,7 +149,7 @@ static int rzg2l_du_probe(struct platform_device *pdev)
 
drm_info(>ddev, "Device %s probed\n", dev_name(>dev));
 
-   drm_fbdev_generic_setup(>ddev, 32);
+   drm_fbdev_dma_setup(>ddev, 32);
 
return 0;
 
-- 
2.44.0



[PATCH v3 07/43] fbdev/deferred-io: Provide get_page hook in struct fb_deferred_io

2024-04-19 Thread Thomas Zimmermann
Add a callback for drivers to provide framebuffer pages to fbdev's
deferred-I/O helpers. Implementations need to acquire a reference on
the page before returning it. Returning NULL generates a SIGBUS
signal.

This will be useful for DRM's fbdev emulation with GEM-shmem buffer
objects.

v2:
- fix typo in commit message (Javier)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/video/fbdev/core/fb_defio.c | 4 
 include/linux/fb.h  | 1 +
 2 files changed, 5 insertions(+)

diff --git a/drivers/video/fbdev/core/fb_defio.c 
b/drivers/video/fbdev/core/fb_defio.c
index 6e0bbcfdb01b5..51928ff7961a5 100644
--- a/drivers/video/fbdev/core/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
@@ -25,9 +25,13 @@
 
 static struct page *fb_deferred_io_get_page(struct fb_info *info, unsigned 
long offs)
 {
+   struct fb_deferred_io *fbdefio = info->fbdefio;
const void *screen_buffer = info->screen_buffer;
struct page *page = NULL;
 
+   if (fbdefio->get_page)
+   return fbdefio->get_page(info, offs);
+
if (is_vmalloc_addr(screen_buffer + offs))
page = vmalloc_to_page(screen_buffer + offs);
else if (info->fix.smem_start)
diff --git a/include/linux/fb.h b/include/linux/fb.h
index 3417103885e27..4eb6afa93737c 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -225,6 +225,7 @@ struct fb_deferred_io {
struct mutex lock; /* mutex that protects the pageref list */
struct list_head pagereflist; /* list of pagerefs for touched pages */
/* callback */
+   struct page *(*get_page)(struct fb_info *info, unsigned long offset);
void (*deferred_io)(struct fb_info *info, struct list_head *pagelist);
 };
 #endif
-- 
2.44.0



[PATCH v3 16/43] drm/tiny/ofdrm: Use fbdev-shmem

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-shmem. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Cc: Thomas Zimmermann 
Cc: Javier Martinez Canillas 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/tiny/ofdrm.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tiny/ofdrm.c b/drivers/gpu/drm/tiny/ofdrm.c
index ab89b7fc7bf61..35996f7eedac0 100644
--- a/drivers/gpu/drm/tiny/ofdrm.c
+++ b/drivers/gpu/drm/tiny/ofdrm.c
@@ -11,7 +11,7 @@
 #include 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -1377,7 +1377,7 @@ static int ofdrm_probe(struct platform_device *pdev)
if (color_mode == 16)
color_mode = odev->format->depth; // can be 15 or 16
 
-   drm_fbdev_generic_setup(dev, color_mode);
+   drm_fbdev_shmem_setup(dev, color_mode);
 
return 0;
 }
-- 
2.44.0



[PATCH v3 36/43] drm/tiny/ili9486: Use fbdev-dma

2024-04-19 Thread Thomas Zimmermann
Implement fbdev emulation with fbdev-dma. Fbdev-dma now supports
damage handling, which is required by ili9486. Avoids the overhead of
fbdev-generic's additional shadow buffering. No functional changes.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/tiny/ili9486.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/gpu/drm/tiny/ili9486.c b/drivers/gpu/drm/tiny/ili9486.c
index 938bceed59998..70d3662600410 100644
--- a/drivers/gpu/drm/tiny/ili9486.c
+++ b/drivers/gpu/drm/tiny/ili9486.c
@@ -16,7 +16,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -247,7 +247,7 @@ static int ili9486_probe(struct spi_device *spi)
 
spi_set_drvdata(spi, drm);
 
-   drm_fbdev_generic_setup(drm, 0);
+   drm_fbdev_dma_setup(drm, 0);
 
return 0;
 }
-- 
2.44.0



[PATCH v3 08/43] drm/fbdev: Add fbdev-shmem

2024-04-19 Thread Thomas Zimmermann
Add an fbdev emulation for SHMEM-based memory managers. The code is
similar to fbdev-generic, but does not require an additional shadow
buffer for mmap(). Fbdev-shmem operates directly on the buffer object's
SHMEM pages. Fbdev's deferred-I/O mechanism updates the hardware state
on write operations.

The memory pages of GEM SHMEM cannot be detected by fbdefio. Therefore
fbdev-shmem implements the .get_page() hook in struct fb_deferred_io.
The fbdefio helpers call this hook to retrieve the page directly from
fbdev-shmem instead of trying to detect it internally.

v3:
- clarify on get_page mechanism in commit description (Javier)
v2:
- use drm_driver_legacy_fb_format() (Geert)

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 drivers/gpu/drm/Makefile  |   1 +
 drivers/gpu/drm/drm_fbdev_shmem.c | 316 ++
 include/drm/drm_fbdev_shmem.h |  15 ++
 3 files changed, 332 insertions(+)
 create mode 100644 drivers/gpu/drm/drm_fbdev_shmem.c
 create mode 100644 include/drm/drm_fbdev_shmem.h

diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index a73c04d2d7a39..50a2f0cffdac2 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -107,6 +107,7 @@ drm_dma_helper-$(CONFIG_DRM_KMS_HELPER) += 
drm_fb_dma_helper.o
 obj-$(CONFIG_DRM_GEM_DMA_HELPER) += drm_dma_helper.o
 
 drm_shmem_helper-y := drm_gem_shmem_helper.o
+drm_shmem_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_shmem.o
 obj-$(CONFIG_DRM_GEM_SHMEM_HELPER) += drm_shmem_helper.o
 
 drm_suballoc_helper-y := drm_suballoc.o
diff --git a/drivers/gpu/drm/drm_fbdev_shmem.c 
b/drivers/gpu/drm/drm_fbdev_shmem.c
new file mode 100644
index 0..a85a8a8e2eb8b
--- /dev/null
+++ b/drivers/gpu/drm/drm_fbdev_shmem.c
@@ -0,0 +1,316 @@
+// SPDX-License-Identifier: MIT
+
+#include 
+
+#include 
+#include 
+#include 
+#include 
+#include 
+#include 
+
+#include 
+
+/*
+ * struct fb_ops
+ */
+
+static int drm_fbdev_shmem_fb_open(struct fb_info *info, int user)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+
+   /* No need to take a ref for fbcon because it unbinds on unregister */
+   if (user && !try_module_get(fb_helper->dev->driver->fops->owner))
+   return -ENODEV;
+
+   return 0;
+}
+
+static int drm_fbdev_shmem_fb_release(struct fb_info *info, int user)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+
+   if (user)
+   module_put(fb_helper->dev->driver->fops->owner);
+
+   return 0;
+}
+
+FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_shmem,
+  drm_fb_helper_damage_range,
+  drm_fb_helper_damage_area);
+
+static int drm_fbdev_shmem_fb_mmap(struct fb_info *info, struct vm_area_struct 
*vma)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+   struct drm_framebuffer *fb = fb_helper->fb;
+   struct drm_gem_object *obj = drm_gem_fb_get_obj(fb, 0);
+   struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+
+   if (shmem->map_wc)
+   vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
+
+   return fb_deferred_io_mmap(info, vma);
+}
+
+static void drm_fbdev_shmem_fb_destroy(struct fb_info *info)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+
+   if (!fb_helper->dev)
+   return;
+
+   drm_fb_helper_fini(fb_helper);
+
+   drm_client_buffer_vunmap(fb_helper->buffer);
+   drm_client_framebuffer_delete(fb_helper->buffer);
+   drm_client_release(_helper->client);
+   drm_fb_helper_unprepare(fb_helper);
+   kfree(fb_helper);
+}
+
+static const struct fb_ops drm_fbdev_shmem_fb_ops = {
+   .owner = THIS_MODULE,
+   .fb_open = drm_fbdev_shmem_fb_open,
+   .fb_release = drm_fbdev_shmem_fb_release,
+   __FB_DEFAULT_DEFERRED_OPS_RDWR(drm_fbdev_shmem),
+   DRM_FB_HELPER_DEFAULT_OPS,
+   __FB_DEFAULT_DEFERRED_OPS_DRAW(drm_fbdev_shmem),
+   .fb_mmap = drm_fbdev_shmem_fb_mmap,
+   .fb_destroy = drm_fbdev_shmem_fb_destroy,
+};
+
+static struct page *drm_fbdev_shmem_get_page(struct fb_info *info, unsigned 
long offset)
+{
+   struct drm_fb_helper *fb_helper = info->par;
+   struct drm_framebuffer *fb = fb_helper->fb;
+   struct drm_gem_object *obj = drm_gem_fb_get_obj(fb, 0);
+   struct drm_gem_shmem_object *shmem = to_drm_gem_shmem_obj(obj);
+   unsigned int i = offset >> PAGE_SHIFT;
+   struct page *page;
+
+   if (fb_WARN_ON_ONCE(info, offset > obj->size))
+   return NULL;
+
+   page = shmem->pages[i]; // protected by active vmap
+   if (page)
+   get_page(page);
+   fb_WARN_ON_ONCE(info, !page);
+
+   return page;
+}
+
+/*
+ * struct drm_fb_helper
+ */
+
+static int drm_fbdev_shmem_helper_fb_probe(struct drm_fb_helper *fb_helper,
+  stru

[PATCH v3 42/43] drm/fbdev-generic: Convert to fbdev-ttm

2024-04-19 Thread Thomas Zimmermann
Only TTM-based drivers use fbdev-generic. Rename it to fbdev-ttm and
change the symbol infix from _generic_ to _ttm_. Link the source file
into TTM helpers, so that it is only build if TTM-based drivers have
been selected. Select DRM_TTM_HELPER for loongson.

Signed-off-by: Thomas Zimmermann 
Reviewed-by: Javier Martinez Canillas 
---
 Documentation/gpu/drm-kms-helpers.rst |  2 +-
 drivers/gpu/drm/Makefile  |  5 +-
 drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c   |  6 +-
 .../{drm_fbdev_generic.c => drm_fbdev_ttm.c}  | 80 +--
 .../gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c   |  4 +-
 drivers/gpu/drm/loongson/Kconfig  |  1 +
 drivers/gpu/drm/loongson/lsdc_drv.c   |  4 +-
 drivers/gpu/drm/nouveau/nouveau_drm.c |  6 +-
 drivers/gpu/drm/qxl/qxl_drv.c |  4 +-
 drivers/gpu/drm/tiny/bochs.c  |  4 +-
 drivers/gpu/drm/vboxvideo/vbox_drv.c  |  4 +-
 drivers/gpu/drm/vmwgfx/vmwgfx_drv.c   |  4 +-
 include/drm/drm_fbdev_generic.h   | 15 
 include/drm/drm_fbdev_ttm.h   | 15 
 14 files changed, 77 insertions(+), 77 deletions(-)
 rename drivers/gpu/drm/{drm_fbdev_generic.c => drm_fbdev_ttm.c} (76%)
 delete mode 100644 include/drm/drm_fbdev_generic.h
 create mode 100644 include/drm/drm_fbdev_ttm.h

diff --git a/Documentation/gpu/drm-kms-helpers.rst 
b/Documentation/gpu/drm-kms-helpers.rst
index 59cfe8a7a8bac..e46ab9b670acd 100644
--- a/Documentation/gpu/drm-kms-helpers.rst
+++ b/Documentation/gpu/drm-kms-helpers.rst
@@ -116,7 +116,7 @@ fbdev Helper Functions Reference
 .. kernel-doc:: drivers/gpu/drm/drm_fb_helper.c
:export:
 
-.. kernel-doc:: drivers/gpu/drm/drm_fbdev_generic.c
+.. kernel-doc:: drivers/gpu/drm/drm_fbdev_ttm.c
:export:
 
 format Helper Functions Reference
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 50a2f0cffdac2..7bd4c525fd825 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -117,6 +117,7 @@ drm_vram_helper-y := drm_gem_vram_helper.o
 obj-$(CONFIG_DRM_VRAM_HELPER) += drm_vram_helper.o
 
 drm_ttm_helper-y := drm_gem_ttm_helper.o
+drm_ttm_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fbdev_ttm.o
 obj-$(CONFIG_DRM_TTM_HELPER) += drm_ttm_helper.o
 
 #
@@ -142,9 +143,7 @@ drm_kms_helper-y := \
drm_self_refresh_helper.o \
drm_simple_kms_helper.o
 drm_kms_helper-$(CONFIG_DRM_PANEL_BRIDGE) += bridge/panel.o
-drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += \
-   drm_fbdev_generic.o \
-   drm_fb_helper.o
+drm_kms_helper-$(CONFIG_DRM_FBDEV_EMULATION) += drm_fb_helper.o
 obj-$(CONFIG_DRM_KMS_HELPER) += drm_kms_helper.o
 
 #
diff --git a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c 
b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
index e4277298cf1aa..a4a63daab9e10 100644
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c
@@ -24,7 +24,7 @@
 
 #include 
 #include 
-#include 
+#include 
 #include 
 #include 
 #include 
@@ -2318,9 +2318,9 @@ static int amdgpu_pci_probe(struct pci_dev *pdev,
!list_empty(_to_drm(adev)->mode_config.connector_list)) {
/* select 8 bpp console on low vram cards */
if (adev->gmc.real_vram_size <= (32*1024*1024))
-   drm_fbdev_generic_setup(adev_to_drm(adev), 8);
+   drm_fbdev_ttm_setup(adev_to_drm(adev), 8);
else
-   drm_fbdev_generic_setup(adev_to_drm(adev), 32);
+   drm_fbdev_ttm_setup(adev_to_drm(adev), 32);
}
 
ret = amdgpu_debugfs_init(adev);
diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
b/drivers/gpu/drm/drm_fbdev_ttm.c
similarity index 76%
rename from drivers/gpu/drm/drm_fbdev_generic.c
rename to drivers/gpu/drm/drm_fbdev_ttm.c
index 97e579c33d84a..bb7898cd7dc63 100644
--- a/drivers/gpu/drm/drm_fbdev_generic.c
+++ b/drivers/gpu/drm/drm_fbdev_ttm.c
@@ -10,10 +10,10 @@
 #include 
 #include 
 
-#include 
+#include 
 
 /* @user: 1=userspace, 0=fbcon */
-static int drm_fbdev_generic_fb_open(struct fb_info *info, int user)
+static int drm_fbdev_ttm_fb_open(struct fb_info *info, int user)
 {
struct drm_fb_helper *fb_helper = info->par;
 
@@ -24,7 +24,7 @@ static int drm_fbdev_generic_fb_open(struct fb_info *info, 
int user)
return 0;
 }
 
-static int drm_fbdev_generic_fb_release(struct fb_info *info, int user)
+static int drm_fbdev_ttm_fb_release(struct fb_info *info, int user)
 {
struct drm_fb_helper *fb_helper = info->par;
 
@@ -34,11 +34,11 @@ static int drm_fbdev_generic_fb_release(struct fb_info 
*info, int user)
return 0;
 }
 
-FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_generic,
+FB_GEN_DEFAULT_DEFERRED_SYSMEM_OPS(drm_fbdev_ttm,
   drm_fb_helper_damage_range,
   drm_fb_helper_damage_area);
 
-static void drm_fbdev_generic_fb_destroy(struct fb_inf

[PATCH v3 01/43] drm/fbdev-generic: Do not set physical framebuffer address

2024-04-19 Thread Thomas Zimmermann
Framebuffer memory is allocated via vzalloc() from non-contiguous
physical pages. The physical framebuffer start address is therefore
meaningless. Do not set it.

The value is not used within the kernel and only exported to userspace
on dedicated ARM configs. No functional change is expected.

v2:
- refer to vzalloc() in commit message (Javier)

Signed-off-by: Thomas Zimmermann 
Fixes: a5b44c4adb16 ("drm/fbdev-generic: Always use shadow buffering")
Cc: Thomas Zimmermann 
Cc: Javier Martinez Canillas 
Cc: Zack Rusin 
Cc: Maarten Lankhorst 
Cc: Maxime Ripard 
Cc:  # v6.4+
Reviewed-by: Javier Martinez Canillas 
Reviewed-by: Zack Rusin 
Reviewed-by: Sui Jingfeng 
Tested-by: Sui Jingfeng 
Acked-by: Maxime Ripard 
---
 drivers/gpu/drm/drm_fbdev_generic.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/gpu/drm/drm_fbdev_generic.c 
b/drivers/gpu/drm/drm_fbdev_generic.c
index be357f926faec..97e579c33d84a 100644
--- a/drivers/gpu/drm/drm_fbdev_generic.c
+++ b/drivers/gpu/drm/drm_fbdev_generic.c
@@ -113,7 +113,6 @@ static int drm_fbdev_generic_helper_fb_probe(struct 
drm_fb_helper *fb_helper,
/* screen */
info->flags |= FBINFO_VIRTFB | FBINFO_READS_FAST;
info->screen_buffer = screen_buffer;
-   info->fix.smem_start = 
page_to_phys(vmalloc_to_page(info->screen_buffer));
info->fix.smem_len = screen_size;
 
/* deferred I/O */
-- 
2.44.0



  1   2   3   4   5   6   7   8   9   10   >