From c3bda715438a5d30e67abf6830a2f01f36500f43 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 13 Nov 2024 17:50:11 -0500 Subject: [PATCH 01/16] drm/i915/display: Convert i915_suspend into i9xx_display_sr These save & restore functions inside i915_suspend are old display functions to save and restore a bunch of display related registers. Move it under display and rename accordantly. Just don't move it entirely towards intel_display struct yet because it depends on drm_i915_private for the IS_MOBILE. While doing this conversion also update the MIT header using the new SPDX ones. v2: Fix Makefile and include (Jani) Removed vga and gmbus (Jani, Ville) Cc: Jesse Barnes Cc: Jani Nikula Reviewed-by: Jani Nikula Reviewed-by: Jonathan Cavitt Link: https://patchwork.freedesktop.org/patch/msgid/20241113225016.208673-2-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/Makefile | 2 +- .../gpu/drm/i915/display/i9xx_display_sr.c | 95 ++++++++++++ .../gpu/drm/i915/display/i9xx_display_sr.h | 14 ++ drivers/gpu/drm/i915/i915_driver.c | 6 +- drivers/gpu/drm/i915/i915_suspend.c | 135 ------------------ drivers/gpu/drm/i915/i915_suspend.h | 14 -- 6 files changed, 113 insertions(+), 153 deletions(-) create mode 100644 drivers/gpu/drm/i915/display/i9xx_display_sr.c create mode 100644 drivers/gpu/drm/i915/display/i9xx_display_sr.h delete mode 100644 drivers/gpu/drm/i915/i915_suspend.c delete mode 100644 drivers/gpu/drm/i915/i915_suspend.h diff --git a/drivers/gpu/drm/i915/Makefile b/drivers/gpu/drm/i915/Makefile index 31710d98cad5..e465828d748f 100644 --- a/drivers/gpu/drm/i915/Makefile +++ b/drivers/gpu/drm/i915/Makefile @@ -30,7 +30,6 @@ i915-y += \ i915_params.o \ i915_pci.o \ i915_scatterlist.o \ - i915_suspend.o \ i915_switcheroo.o \ i915_sysfs.o \ i915_utils.o \ @@ -220,6 +219,7 @@ i915-$(CONFIG_HWMON) += \ i915-y += \ display/hsw_ips.o \ display/i9xx_plane.o \ + display/i9xx_display_sr.o \ display/i9xx_wm.o \ display/intel_alpm.o \ display/intel_atomic.o \ diff --git a/drivers/gpu/drm/i915/display/i9xx_display_sr.c b/drivers/gpu/drm/i915/display/i9xx_display_sr.c new file mode 100644 index 000000000000..4dd0ce267994 --- /dev/null +++ b/drivers/gpu/drm/i915/display/i9xx_display_sr.c @@ -0,0 +1,95 @@ +// SPDX-License-Identifier: MIT +/* + * Copyright © 2024 Intel Corporation + */ + +#include "i915_drv.h" +#include "i915_reg.h" +#include "i9xx_display_sr.h" +#include "intel_de.h" +#include "intel_gmbus.h" +#include "intel_pci_config.h" + +static void i9xx_display_save_swf(struct drm_i915_private *i915) +{ + int i; + + /* Scratch space */ + if (GRAPHICS_VER(i915) == 2 && IS_MOBILE(i915)) { + for (i = 0; i < 7; i++) { + i915->regfile.saveSWF0[i] = intel_de_read(i915, SWF0(i915, i)); + i915->regfile.saveSWF1[i] = intel_de_read(i915, SWF1(i915, i)); + } + for (i = 0; i < 3; i++) + i915->regfile.saveSWF3[i] = intel_de_read(i915, SWF3(i915, i)); + } else if (GRAPHICS_VER(i915) == 2) { + for (i = 0; i < 7; i++) + i915->regfile.saveSWF1[i] = intel_de_read(i915, SWF1(i915, i)); + } else if (HAS_GMCH(i915)) { + for (i = 0; i < 16; i++) { + i915->regfile.saveSWF0[i] = intel_de_read(i915, SWF0(i915, i)); + i915->regfile.saveSWF1[i] = intel_de_read(i915, SWF1(i915, i)); + } + for (i = 0; i < 3; i++) + i915->regfile.saveSWF3[i] = intel_de_read(i915, SWF3(i915, i)); + } +} + +static void i9xx_display_restore_swf(struct drm_i915_private *i915) +{ + int i; + + /* Scratch space */ + if (GRAPHICS_VER(i915) == 2 && IS_MOBILE(i915)) { + for (i = 0; i < 7; i++) { + intel_de_write(i915, SWF0(i915, i), i915->regfile.saveSWF0[i]); + intel_de_write(i915, SWF1(i915, i), i915->regfile.saveSWF1[i]); + } + for (i = 0; i < 3; i++) + intel_de_write(i915, SWF3(i915, i), i915->regfile.saveSWF3[i]); + } else if (GRAPHICS_VER(i915) == 2) { + for (i = 0; i < 7; i++) + intel_de_write(i915, SWF1(i915, i), i915->regfile.saveSWF1[i]); + } else if (HAS_GMCH(i915)) { + for (i = 0; i < 16; i++) { + intel_de_write(i915, SWF0(i915, i), i915->regfile.saveSWF0[i]); + intel_de_write(i915, SWF1(i915, i), i915->regfile.saveSWF1[i]); + } + for (i = 0; i < 3; i++) + intel_de_write(i915, SWF3(i915, i), i915->regfile.saveSWF3[i]); + } +} + +void i9xx_display_sr_save(struct drm_i915_private *i915) +{ + struct pci_dev *pdev = to_pci_dev(i915->drm.dev); + + if (!HAS_DISPLAY(i915)) + return; + + /* Display arbitration control */ + if (GRAPHICS_VER(i915) <= 4) + i915->regfile.saveDSPARB = intel_de_read(i915, DSPARB(i915)); + + if (GRAPHICS_VER(i915) == 4) + pci_read_config_word(pdev, GCDGMBUS, &i915->regfile.saveGCDGMBUS); + + i9xx_display_save_swf(i915); +} + +void i9xx_display_sr_restore(struct drm_i915_private *i915) +{ + struct pci_dev *pdev = to_pci_dev(i915->drm.dev); + + if (!HAS_DISPLAY(i915)) + return; + + i9xx_display_restore_swf(i915); + + if (GRAPHICS_VER(i915) == 4) + pci_write_config_word(pdev, GCDGMBUS, i915->regfile.saveGCDGMBUS); + + /* Display arbitration */ + if (GRAPHICS_VER(i915) <= 4) + intel_de_write(i915, DSPARB(i915), i915->regfile.saveDSPARB); +} diff --git a/drivers/gpu/drm/i915/display/i9xx_display_sr.h b/drivers/gpu/drm/i915/display/i9xx_display_sr.h new file mode 100644 index 000000000000..30383758f97e --- /dev/null +++ b/drivers/gpu/drm/i915/display/i9xx_display_sr.h @@ -0,0 +1,14 @@ +/* SPDX-License-Identifier: MIT */ +/* + * Copyright © 2024 Intel Corporation + */ + +#ifndef __I9XX_DISPLAY_SR_H__ +#define __I9XX_DISPLAY_SR_H__ + +struct drm_i915_private; + +void i9xx_display_sr_save(struct drm_i915_private *i915); +void i9xx_display_sr_restore(struct drm_i915_private *i915); + +#endif diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 1c263116e765..88b30a099436 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -45,6 +45,7 @@ #include #include +#include "display/i9xx_display_sr.h" #include "display/intel_acpi.h" #include "display/intel_bw.h" #include "display/intel_cdclk.h" @@ -94,7 +95,6 @@ #include "i915_memcpy.h" #include "i915_perf.h" #include "i915_query.h" -#include "i915_suspend.h" #include "i915_switcheroo.h" #include "i915_sysfs.h" #include "i915_utils.h" @@ -1054,7 +1054,7 @@ static int i915_drm_suspend(struct drm_device *dev) intel_dpt_suspend(dev_priv); i915_ggtt_suspend(to_gt(dev_priv)->ggtt); - i915_save_display(dev_priv); + i9xx_display_sr_save(dev_priv); opregion_target_state = suspend_to_idle(dev_priv) ? PCI_D1 : PCI_D3cold; intel_opregion_suspend(display, opregion_target_state); @@ -1173,7 +1173,7 @@ static int i915_drm_resume(struct drm_device *dev) intel_dmc_resume(display); - i915_restore_display(dev_priv); + i9xx_display_sr_restore(dev_priv); intel_vga_redisable(display); diff --git a/drivers/gpu/drm/i915/i915_suspend.c b/drivers/gpu/drm/i915/i915_suspend.c deleted file mode 100644 index fb67b05cd864..000000000000 --- a/drivers/gpu/drm/i915/i915_suspend.c +++ /dev/null @@ -1,135 +0,0 @@ -/* - * - * Copyright 2008 (c) Intel Corporation - * Jesse Barnes - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, sub license, and/or sell copies of the Software, and to - * permit persons to whom the Software is furnished to do so, subject to - * the following conditions: - * - * The above copyright notice and this permission notice (including the - * next paragraph) shall be included in all copies or substantial portions - * of the Software. - * - * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS - * OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. - * IN NO EVENT SHALL TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR - * ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, - * TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE - * SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - */ - -#include "display/intel_de.h" -#include "display/intel_gmbus.h" - -#include "i915_drv.h" -#include "i915_reg.h" -#include "i915_suspend.h" -#include "intel_pci_config.h" - -static void intel_save_swf(struct drm_i915_private *dev_priv) -{ - int i; - - /* Scratch space */ - if (GRAPHICS_VER(dev_priv) == 2 && IS_MOBILE(dev_priv)) { - for (i = 0; i < 7; i++) { - dev_priv->regfile.saveSWF0[i] = intel_de_read(dev_priv, - SWF0(dev_priv, i)); - dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv, - SWF1(dev_priv, i)); - } - for (i = 0; i < 3; i++) - dev_priv->regfile.saveSWF3[i] = intel_de_read(dev_priv, - SWF3(dev_priv, i)); - } else if (GRAPHICS_VER(dev_priv) == 2) { - for (i = 0; i < 7; i++) - dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv, - SWF1(dev_priv, i)); - } else if (HAS_GMCH(dev_priv)) { - for (i = 0; i < 16; i++) { - dev_priv->regfile.saveSWF0[i] = intel_de_read(dev_priv, - SWF0(dev_priv, i)); - dev_priv->regfile.saveSWF1[i] = intel_de_read(dev_priv, - SWF1(dev_priv, i)); - } - for (i = 0; i < 3; i++) - dev_priv->regfile.saveSWF3[i] = intel_de_read(dev_priv, - SWF3(dev_priv, i)); - } -} - -static void intel_restore_swf(struct drm_i915_private *dev_priv) -{ - int i; - - /* Scratch space */ - if (GRAPHICS_VER(dev_priv) == 2 && IS_MOBILE(dev_priv)) { - for (i = 0; i < 7; i++) { - intel_de_write(dev_priv, SWF0(dev_priv, i), - dev_priv->regfile.saveSWF0[i]); - intel_de_write(dev_priv, SWF1(dev_priv, i), - dev_priv->regfile.saveSWF1[i]); - } - for (i = 0; i < 3; i++) - intel_de_write(dev_priv, SWF3(dev_priv, i), - dev_priv->regfile.saveSWF3[i]); - } else if (GRAPHICS_VER(dev_priv) == 2) { - for (i = 0; i < 7; i++) - intel_de_write(dev_priv, SWF1(dev_priv, i), - dev_priv->regfile.saveSWF1[i]); - } else if (HAS_GMCH(dev_priv)) { - for (i = 0; i < 16; i++) { - intel_de_write(dev_priv, SWF0(dev_priv, i), - dev_priv->regfile.saveSWF0[i]); - intel_de_write(dev_priv, SWF1(dev_priv, i), - dev_priv->regfile.saveSWF1[i]); - } - for (i = 0; i < 3; i++) - intel_de_write(dev_priv, SWF3(dev_priv, i), - dev_priv->regfile.saveSWF3[i]); - } -} - -void i915_save_display(struct drm_i915_private *dev_priv) -{ - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); - - if (!HAS_DISPLAY(dev_priv)) - return; - - /* Display arbitration control */ - if (GRAPHICS_VER(dev_priv) <= 4) - dev_priv->regfile.saveDSPARB = intel_de_read(dev_priv, - DSPARB(dev_priv)); - - if (GRAPHICS_VER(dev_priv) == 4) - pci_read_config_word(pdev, GCDGMBUS, - &dev_priv->regfile.saveGCDGMBUS); - - intel_save_swf(dev_priv); -} - -void i915_restore_display(struct drm_i915_private *dev_priv) -{ - struct pci_dev *pdev = to_pci_dev(dev_priv->drm.dev); - - if (!HAS_DISPLAY(dev_priv)) - return; - - intel_restore_swf(dev_priv); - - if (GRAPHICS_VER(dev_priv) == 4) - pci_write_config_word(pdev, GCDGMBUS, - dev_priv->regfile.saveGCDGMBUS); - - /* Display arbitration */ - if (GRAPHICS_VER(dev_priv) <= 4) - intel_de_write(dev_priv, DSPARB(dev_priv), - dev_priv->regfile.saveDSPARB); -} diff --git a/drivers/gpu/drm/i915/i915_suspend.h b/drivers/gpu/drm/i915/i915_suspend.h deleted file mode 100644 index e5a611ee3d15..000000000000 --- a/drivers/gpu/drm/i915/i915_suspend.h +++ /dev/null @@ -1,14 +0,0 @@ -/* SPDX-License-Identifier: MIT */ -/* - * Copyright © 2019 Intel Corporation - */ - -#ifndef __I915_SUSPEND_H__ -#define __I915_SUSPEND_H__ - -struct drm_i915_private; - -void i915_save_display(struct drm_i915_private *i915); -void i915_restore_display(struct drm_i915_private *i915); - -#endif /* __I915_SUSPEND_H__ */ -- 2.50.1 From ec803c9b00324fb884ea40ef1d17432dcb8e83b3 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 13 Nov 2024 17:50:12 -0500 Subject: [PATCH 02/16] drm/i915/display: Move regfile registers intel_display.restore The intel_display struct already has a place for save/restore stuff. Move the i915's regfile there since they are only related to display. Reviewed-by: Jonathan Cavitt Link: https://patchwork.freedesktop.org/patch/msgid/20241113225016.208673-3-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- .../gpu/drm/i915/display/i9xx_display_sr.c | 40 ++++++++++--------- .../gpu/drm/i915/display/intel_display_core.h | 5 +++ drivers/gpu/drm/i915/i915_drv.h | 9 ----- 3 files changed, 27 insertions(+), 27 deletions(-) diff --git a/drivers/gpu/drm/i915/display/i9xx_display_sr.c b/drivers/gpu/drm/i915/display/i9xx_display_sr.c index 4dd0ce267994..4c78b7165831 100644 --- a/drivers/gpu/drm/i915/display/i9xx_display_sr.c +++ b/drivers/gpu/drm/i915/display/i9xx_display_sr.c @@ -12,56 +12,59 @@ static void i9xx_display_save_swf(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; int i; /* Scratch space */ if (GRAPHICS_VER(i915) == 2 && IS_MOBILE(i915)) { for (i = 0; i < 7; i++) { - i915->regfile.saveSWF0[i] = intel_de_read(i915, SWF0(i915, i)); - i915->regfile.saveSWF1[i] = intel_de_read(i915, SWF1(i915, i)); + display->restore.saveSWF0[i] = intel_de_read(display, SWF0(i915, i)); + display->restore.saveSWF1[i] = intel_de_read(display, SWF1(i915, i)); } for (i = 0; i < 3; i++) - i915->regfile.saveSWF3[i] = intel_de_read(i915, SWF3(i915, i)); + display->restore.saveSWF3[i] = intel_de_read(display, SWF3(i915, i)); } else if (GRAPHICS_VER(i915) == 2) { for (i = 0; i < 7; i++) - i915->regfile.saveSWF1[i] = intel_de_read(i915, SWF1(i915, i)); + display->restore.saveSWF1[i] = intel_de_read(display, SWF1(i915, i)); } else if (HAS_GMCH(i915)) { for (i = 0; i < 16; i++) { - i915->regfile.saveSWF0[i] = intel_de_read(i915, SWF0(i915, i)); - i915->regfile.saveSWF1[i] = intel_de_read(i915, SWF1(i915, i)); + display->restore.saveSWF0[i] = intel_de_read(display, SWF0(i915, i)); + display->restore.saveSWF1[i] = intel_de_read(display, SWF1(i915, i)); } for (i = 0; i < 3; i++) - i915->regfile.saveSWF3[i] = intel_de_read(i915, SWF3(i915, i)); + display->restore.saveSWF3[i] = intel_de_read(display, SWF3(i915, i)); } } static void i9xx_display_restore_swf(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; int i; /* Scratch space */ if (GRAPHICS_VER(i915) == 2 && IS_MOBILE(i915)) { for (i = 0; i < 7; i++) { - intel_de_write(i915, SWF0(i915, i), i915->regfile.saveSWF0[i]); - intel_de_write(i915, SWF1(i915, i), i915->regfile.saveSWF1[i]); + intel_de_write(display, SWF0(i915, i), display->restore.saveSWF0[i]); + intel_de_write(display, SWF1(i915, i), display->restore.saveSWF1[i]); } for (i = 0; i < 3; i++) - intel_de_write(i915, SWF3(i915, i), i915->regfile.saveSWF3[i]); + intel_de_write(display, SWF3(i915, i), display->restore.saveSWF3[i]); } else if (GRAPHICS_VER(i915) == 2) { for (i = 0; i < 7; i++) - intel_de_write(i915, SWF1(i915, i), i915->regfile.saveSWF1[i]); + intel_de_write(display, SWF1(i915, i), display->restore.saveSWF1[i]); } else if (HAS_GMCH(i915)) { for (i = 0; i < 16; i++) { - intel_de_write(i915, SWF0(i915, i), i915->regfile.saveSWF0[i]); - intel_de_write(i915, SWF1(i915, i), i915->regfile.saveSWF1[i]); + intel_de_write(display, SWF0(i915, i), display->restore.saveSWF0[i]); + intel_de_write(display, SWF1(i915, i), display->restore.saveSWF1[i]); } for (i = 0; i < 3; i++) - intel_de_write(i915, SWF3(i915, i), i915->regfile.saveSWF3[i]); + intel_de_write(display, SWF3(i915, i), display->restore.saveSWF3[i]); } } void i9xx_display_sr_save(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct pci_dev *pdev = to_pci_dev(i915->drm.dev); if (!HAS_DISPLAY(i915)) @@ -69,16 +72,17 @@ void i9xx_display_sr_save(struct drm_i915_private *i915) /* Display arbitration control */ if (GRAPHICS_VER(i915) <= 4) - i915->regfile.saveDSPARB = intel_de_read(i915, DSPARB(i915)); + display->restore.saveDSPARB = intel_de_read(display, DSPARB(i915)); if (GRAPHICS_VER(i915) == 4) - pci_read_config_word(pdev, GCDGMBUS, &i915->regfile.saveGCDGMBUS); + pci_read_config_word(pdev, GCDGMBUS, &display->restore.saveGCDGMBUS); i9xx_display_save_swf(i915); } void i9xx_display_sr_restore(struct drm_i915_private *i915) { + struct intel_display *display = &i915->display; struct pci_dev *pdev = to_pci_dev(i915->drm.dev); if (!HAS_DISPLAY(i915)) @@ -87,9 +91,9 @@ void i9xx_display_sr_restore(struct drm_i915_private *i915) i9xx_display_restore_swf(i915); if (GRAPHICS_VER(i915) == 4) - pci_write_config_word(pdev, GCDGMBUS, i915->regfile.saveGCDGMBUS); + pci_write_config_word(pdev, GCDGMBUS, display->restore.saveGCDGMBUS); /* Display arbitration */ if (GRAPHICS_VER(i915) <= 4) - intel_de_write(i915, DSPARB(i915), i915->regfile.saveDSPARB); + intel_de_write(display, DSPARB(i915), display->restore.saveDSPARB); } diff --git a/drivers/gpu/drm/i915/display/intel_display_core.h b/drivers/gpu/drm/i915/display/intel_display_core.h index 45b7c6900adc..f6c1bedf1c31 100644 --- a/drivers/gpu/drm/i915/display/intel_display_core.h +++ b/drivers/gpu/drm/i915/display/intel_display_core.h @@ -505,6 +505,11 @@ struct intel_display { /* restore state for suspend/resume and display reset */ struct drm_atomic_state *modeset_state; struct drm_modeset_acquire_ctx reset_ctx; + u32 saveDSPARB; + u32 saveSWF0[16]; + u32 saveSWF1[16]; + u32 saveSWF3[3]; + u16 saveGCDGMBUS; } restore; struct { diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h index 44d8c51a3245..4131a0dbeb3d 100644 --- a/drivers/gpu/drm/i915/i915_drv.h +++ b/drivers/gpu/drm/i915/i915_drv.h @@ -101,14 +101,6 @@ struct i915_dsm { resource_size_t usable_size; }; -struct i915_suspend_saved_registers { - u32 saveDSPARB; - u32 saveSWF0[16]; - u32 saveSWF1[16]; - u32 saveSWF3[3]; - u16 saveGCDGMBUS; -}; - #define MAX_L3_SLICES 2 struct intel_l3_parity { u32 *remap_info[MAX_L3_SLICES]; @@ -299,7 +291,6 @@ struct drm_i915_private { struct i915_gpu_error gpu_error; u32 suspend_count; - struct i915_suspend_saved_registers regfile; struct vlv_s0ix_state *vlv_s0ix_state; struct dram_info { -- 2.50.1 From bd5dd9797d81e74af5011fc086c9b8e9968c339d Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 13 Nov 2024 17:50:13 -0500 Subject: [PATCH 03/16] drm/{i915, xe}/display: Move DP MST calls to display_driver Move dp_mst suspend/resume functions from the drivers towards intel_display_driver to continue with the unification. Reviewed-by: Jonathan Cavitt Link: https://patchwork.freedesktop.org/patch/msgid/20241113225016.208673-4-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_display_driver.c | 6 ++++++ drivers/gpu/drm/i915/i915_driver.c | 4 ---- drivers/gpu/drm/xe/display/xe_display.c | 7 ------- 3 files changed, 6 insertions(+), 11 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_driver.c b/drivers/gpu/drm/i915/display/intel_display_driver.c index 55262296621e..11a69c71c766 100644 --- a/drivers/gpu/drm/i915/display/intel_display_driver.c +++ b/drivers/gpu/drm/i915/display/intel_display_driver.c @@ -676,6 +676,9 @@ int intel_display_driver_suspend(struct drm_i915_private *i915) ret); else i915->display.restore.modeset_state = state; + + intel_dp_mst_suspend(i915); + return ret; } @@ -729,6 +732,9 @@ void intel_display_driver_resume(struct drm_i915_private *i915) if (!HAS_DISPLAY(i915)) return; + /* MST sideband requires HPD interrupts enabled */ + intel_dp_mst_resume(i915); + i915->display.restore.modeset_state = NULL; if (state) state->acquire_ctx = &ctx; diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index 88b30a099436..c9ed69d7fce8 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1040,8 +1040,6 @@ static int i915_drm_suspend(struct drm_device *dev) intel_display_driver_suspend(dev_priv); - intel_dp_mst_suspend(dev_priv); - intel_irq_suspend(dev_priv); intel_hpd_cancel_work(dev_priv); @@ -1209,8 +1207,6 @@ static int i915_drm_resume(struct drm_device *dev) intel_hpd_init(dev_priv); - /* MST sideband requires HPD interrupts enabled */ - intel_dp_mst_resume(dev_priv); intel_display_driver_resume(dev_priv); if (HAS_DISPLAY(dev_priv)) { diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 9ea2b3d133a0..2b77d706672d 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -334,9 +334,6 @@ static void __xe_display_pm_suspend(struct xe_device *xe, bool runtime) xe_display_flush_cleanup_work(xe); - if (!runtime) - intel_dp_mst_suspend(xe); - intel_hpd_cancel_work(xe); if (!runtime && has_display(xe)) { @@ -447,10 +444,6 @@ static void __xe_display_pm_resume(struct xe_device *xe, bool runtime) if (!runtime && has_display(xe)) intel_display_driver_resume_access(xe); - /* MST sideband requires HPD interrupts enabled */ - if (!runtime) - intel_dp_mst_resume(xe); - if (!runtime && has_display(xe)) { intel_display_driver_resume(xe); drm_kms_helper_poll_enable(&xe->drm); -- 2.50.1 From 0a86a9e8c6c9680f718fbed99879f9e78b16d21d Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 13 Nov 2024 17:50:14 -0500 Subject: [PATCH 04/16] drm/xe/display: Delay hpd_init resume Align with i915 and only initialize hotplugs after the display driver access has been resumed. Reviewed-by: Jonathan Cavitt Link: https://patchwork.freedesktop.org/patch/msgid/20241113225016.208673-5-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/xe/display/xe_display.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index 2b77d706672d..af405f7b4d45 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -439,11 +439,12 @@ static void __xe_display_pm_resume(struct xe_device *xe, bool runtime) drm_mode_config_reset(&xe->drm); intel_display_driver_init_hw(xe); - intel_hpd_init(xe); if (!runtime && has_display(xe)) intel_display_driver_resume_access(xe); + intel_hpd_init(xe); + if (!runtime && has_display(xe)) { intel_display_driver_resume(xe); drm_kms_helper_poll_enable(&xe->drm); -- 2.50.1 From 5772c4e999b70ce0ada481a6b36a62348d633296 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 13 Nov 2024 17:50:15 -0500 Subject: [PATCH 05/16] drm/xe/display: Delay dsm handler registration Bring some consistency to register/unregister order at the same time it aligns with i915 sequence order. Reviewed-by: Jonathan Cavitt Link: https://patchwork.freedesktop.org/patch/msgid/20241113225016.208673-6-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/xe/display/xe_display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index af405f7b4d45..e60eb7c49e5a 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -219,8 +219,8 @@ void xe_display_register(struct xe_device *xe) return; intel_display_driver_register(xe); - intel_register_dsm_handler(); intel_power_domains_enable(xe); + intel_register_dsm_handler(); } void xe_display_unregister(struct xe_device *xe) -- 2.50.1 From a594f284ddce5b152ffe4d938708ed714f796887 Mon Sep 17 00:00:00 2001 From: Rodrigo Vivi Date: Wed, 13 Nov 2024 17:50:16 -0500 Subject: [PATCH 06/16] drm/{i915, xe}: Move power_domains suspend/resume to display_power Move intel_power_domains_{suspend,resume} to inside intel_display_power_{suspend_late, resume_early}. With this also change the VLV suspend failure to call the intel_display_power_resume_early. In the end, the only function executed there for VLV is the intel_power_domains_resume. Besides make the code more consistency give the call that was immediately before: intel_display_power_suspend_late. Reviewed-by: Jonathan Cavitt Link: https://patchwork.freedesktop.org/patch/msgid/20241113225016.208673-7-rodrigo.vivi@intel.com Signed-off-by: Rodrigo Vivi --- drivers/gpu/drm/i915/display/intel_display_power.c | 6 +++++- drivers/gpu/drm/i915/display/intel_display_power.h | 2 +- drivers/gpu/drm/i915/i915_driver.c | 8 ++------ drivers/gpu/drm/xe/display/xe_display.c | 7 ++----- 4 files changed, 10 insertions(+), 13 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.c b/drivers/gpu/drm/i915/display/intel_display_power.c index 2766fd9208b0..59dee2dc0552 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.c +++ b/drivers/gpu/drm/i915/display/intel_display_power.c @@ -2232,10 +2232,12 @@ static void intel_power_domains_verify_state(struct drm_i915_private *i915) #endif -void intel_display_power_suspend_late(struct drm_i915_private *i915) +void intel_display_power_suspend_late(struct drm_i915_private *i915, bool s2idle) { struct intel_display *display = &i915->display; + intel_power_domains_suspend(i915, s2idle); + if (DISPLAY_VER(i915) >= 11 || IS_GEMINILAKE(i915) || IS_BROXTON(i915)) { bxt_enable_dc9(display); @@ -2263,6 +2265,8 @@ void intel_display_power_resume_early(struct drm_i915_private *i915) /* Tweaked Wa_14010685332:cnp,icp,jsp,mcc,tgp,adp */ if (INTEL_PCH_TYPE(i915) >= PCH_CNP && INTEL_PCH_TYPE(i915) < PCH_DG1) intel_de_rmw(i915, SOUTH_CHICKEN1, SBCLK_RUN_REFCLK_DIS, 0); + + intel_power_domains_resume(i915); } void intel_display_power_suspend(struct drm_i915_private *i915) diff --git a/drivers/gpu/drm/i915/display/intel_display_power.h b/drivers/gpu/drm/i915/display/intel_display_power.h index 3f8f84df4733..688f3b60b5c5 100644 --- a/drivers/gpu/drm/i915/display/intel_display_power.h +++ b/drivers/gpu/drm/i915/display/intel_display_power.h @@ -176,7 +176,7 @@ void intel_power_domains_suspend(struct drm_i915_private *dev_priv, bool s2idle) void intel_power_domains_resume(struct drm_i915_private *dev_priv); void intel_power_domains_sanitize_state(struct drm_i915_private *dev_priv); -void intel_display_power_suspend_late(struct drm_i915_private *i915); +void intel_display_power_suspend_late(struct drm_i915_private *i915, bool s2idle); void intel_display_power_resume_early(struct drm_i915_private *i915); void intel_display_power_suspend(struct drm_i915_private *i915); void intel_display_power_resume(struct drm_i915_private *i915); diff --git a/drivers/gpu/drm/i915/i915_driver.c b/drivers/gpu/drm/i915/i915_driver.c index c9ed69d7fce8..b500ccf50410 100644 --- a/drivers/gpu/drm/i915/i915_driver.c +++ b/drivers/gpu/drm/i915/i915_driver.c @@ -1086,14 +1086,12 @@ static int i915_drm_suspend_late(struct drm_device *dev, bool hibernation) for_each_gt(gt, dev_priv, i) intel_uncore_suspend(gt->uncore); - intel_power_domains_suspend(dev_priv, s2idle); - - intel_display_power_suspend_late(dev_priv); + intel_display_power_suspend_late(dev_priv, s2idle); ret = vlv_suspend_complete(dev_priv); if (ret) { drm_err(&dev_priv->drm, "Suspend complete failed: %d\n", ret); - intel_power_domains_resume(dev_priv); + intel_display_power_resume_early(dev_priv); goto out; } @@ -1292,8 +1290,6 @@ static int i915_drm_resume_early(struct drm_device *dev) intel_display_power_resume_early(dev_priv); - intel_power_domains_resume(dev_priv); - enable_rpm_wakeref_asserts(&dev_priv->runtime_pm); return ret; diff --git a/drivers/gpu/drm/xe/display/xe_display.c b/drivers/gpu/drm/xe/display/xe_display.c index e60eb7c49e5a..760847959bc1 100644 --- a/drivers/gpu/drm/xe/display/xe_display.c +++ b/drivers/gpu/drm/xe/display/xe_display.c @@ -395,12 +395,11 @@ void xe_display_pm_runtime_suspend(struct xe_device *xe) void xe_display_pm_suspend_late(struct xe_device *xe) { bool s2idle = suspend_to_idle(); + if (!xe->info.probe_display) return; - intel_power_domains_suspend(xe, s2idle); - - intel_display_power_suspend_late(xe); + intel_display_power_suspend_late(xe, s2idle); } void xe_display_pm_shutdown_late(struct xe_device *xe) @@ -422,8 +421,6 @@ void xe_display_pm_resume_early(struct xe_device *xe) return; intel_display_power_resume_early(xe); - - intel_power_domains_resume(xe); } static void __xe_display_pm_resume(struct xe_device *xe, bool runtime) -- 2.50.1 From af02ee4fb63342c873b747d724cd5ada13c2bde1 Mon Sep 17 00:00:00 2001 From: Arun R Murthy Date: Wed, 25 Sep 2024 09:14:30 +0530 Subject: [PATCH 07/16] drm/i915/dp: use fsleep instead of usleep_range for LT Sleeping for < 10us use udelay, for 10us to 20ms use usleep_range() and for > 10ms use msleep. flseep() will call the particular API based on the above condition. (Documentation/timers/timers-howto.rst) Aux RD Interval value depends on the value read from the dpcd register which is updated from the sink device, hence use flseep. Co-developed-by: Srikanth V NagaVenkata Signed-off-by: Arun R Murthy Reviewed-by: Jani Nikula Signed-off-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20240925034432.1777029-2-arun.r.murthy@intel.com --- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index 397cc4ebae52..f41b69840ad9 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -898,7 +898,7 @@ intel_dp_link_training_clock_recovery(struct intel_dp *intel_dp, voltage_tries = 1; for (cr_tries = 0; cr_tries < max_cr_tries; ++cr_tries) { - usleep_range(delay_us, 2 * delay_us); + fsleep(delay_us); if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, dp_phy, link_status) < 0) { @@ -1040,7 +1040,7 @@ intel_dp_link_training_channel_equalization(struct intel_dp *intel_dp, } for (tries = 0; tries < 5; tries++) { - usleep_range(delay_us, 2 * delay_us); + fsleep(delay_us); if (drm_dp_dpcd_read_phy_link_status(&intel_dp->aux, dp_phy, link_status) < 0) { @@ -1417,7 +1417,7 @@ intel_dp_128b132b_lane_eq(struct intel_dp *intel_dp, deadline = jiffies + msecs_to_jiffies_timeout(400); for (try = 0; try < max_tries; try++) { - usleep_range(delay_us, 2 * delay_us); + fsleep(delay_us); /* * The delay may get updated. The transmitter shall read the -- 2.50.1 From eb0c1757a36cabb730cde4e045eb52587602504d Mon Sep 17 00:00:00 2001 From: Arun R Murthy Date: Fri, 11 Oct 2024 10:28:25 +0530 Subject: [PATCH 08/16] drm/i915/dp: read Aux RD interval just before setting the FFE preset Figure 3-52: 128b132b DP DPTC LANEx_CHANNEL_EQ_DONE Sequence of DP2.1a spec. After reading LANEx_CHANNEL_EQ_DONE, read the FFE presets. AUX_RD_INTERVAL and then write the new FFE presets. v4: Read AUX_RD_INTERVAL before get/set TX FFE preset (Jani) Co-developed-by: Srikanth V NagaVenkata Signed-off-by: Arun R Murthy Reviewed-by: Suraj Kandpal Signed-off-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20241011045825.2629469-1-arun.r.murthy@intel.com --- .../gpu/drm/i915/display/intel_dp_link_training.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index f41b69840ad9..a48a70ca4fb3 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -1419,12 +1419,6 @@ intel_dp_128b132b_lane_eq(struct intel_dp *intel_dp, for (try = 0; try < max_tries; try++) { fsleep(delay_us); - /* - * The delay may get updated. The transmitter shall read the - * delay before link status during link training. - */ - delay_us = drm_dp_128b132b_read_aux_rd_interval(&intel_dp->aux); - if (drm_dp_dpcd_read_link_status(&intel_dp->aux, link_status) < 0) { lt_err(intel_dp, DP_PHY_DPRX, "Failed to read link status\n"); return false; @@ -1451,8 +1445,15 @@ intel_dp_128b132b_lane_eq(struct intel_dp *intel_dp, if (time_after(jiffies, deadline)) timeout = true; /* try one last time after deadline */ - /* Update signal levels and training set as requested. */ + /* + * During LT, Tx shall read AUX_RD_INTERVAL just before writing the new FFE + * presets. + */ + delay_us = drm_dp_128b132b_read_aux_rd_interval(&intel_dp->aux); + intel_dp_get_adjust_train(intel_dp, crtc_state, DP_PHY_DPRX, link_status); + + /* Update signal levels and training set as requested. */ if (!intel_dp_update_link_train(intel_dp, crtc_state, DP_PHY_DPRX)) { lt_err(intel_dp, DP_PHY_DPRX, "Failed to update TX FFE settings\n"); return false; -- 2.50.1 From e725091865407fcd8d96ab9ad618c07fb6e3cc2b Mon Sep 17 00:00:00 2001 From: Arun R Murthy Date: Wed, 25 Sep 2024 09:14:32 +0530 Subject: [PATCH 09/16] drm/i915/dp: Include the time taken by AUX Tx for timeout As per DP spec the timeout for LANE_CHANNEL_EQ_DONE is 400ms. But this timeout value is exclusively for the Aux RD Interval and excludes the time consumed for the AUX Tx (i.e reading/writing FFE presets). Add another 50ms for these AUX Tx to the 400ms timeout. Ref: "Figure 3-52: 128b132b DP DPTC LANEx_CHANNEL_EQ_DONE Sequence" of DP2.1a spec. Co-developed-by: Srikanth V NagaVenkata Signed-off-by: Arun R Murthy Reviewed-by: Suraj Kandpal Acked-by: Jani Nikula Signed-off-by: Suraj Kandpal Link: https://patchwork.freedesktop.org/patch/msgid/20240925034432.1777029-4-arun.r.murthy@intel.com --- drivers/gpu/drm/i915/display/intel_dp_link_training.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_link_training.c b/drivers/gpu/drm/i915/display/intel_dp_link_training.c index a48a70ca4fb3..ea9b4730a176 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_link_training.c +++ b/drivers/gpu/drm/i915/display/intel_dp_link_training.c @@ -1414,7 +1414,7 @@ intel_dp_128b132b_lane_eq(struct intel_dp *intel_dp, } /* Time budget for the LANEx_EQ_DONE Sequence */ - deadline = jiffies + msecs_to_jiffies_timeout(400); + deadline = jiffies + msecs_to_jiffies_timeout(450); for (try = 0; try < max_tries; try++) { fsleep(delay_us); -- 2.50.1 From d58f65df2dcb59acd3965907507cfa608fe924b4 Mon Sep 17 00:00:00 2001 From: Imre Deak Date: Mon, 18 Nov 2024 15:10:44 +0200 Subject: [PATCH 10/16] drm/i915/dp_mst: Fix connector initialization in intel_dp_add_mst_connector() The connector initialization in intel_dp_add_mst_connector() depends on the device pointer in connector to be valid, at least by connector debug printing. The device pointer is initialized by drm_connector_init(), however that function also exposes the connector to in-kernel users, which can't be done before the connector is fully initialized. For now make sure the device pointer is valid before it's used, until a follow-up change moving this to DRM core. This issue was revealed by the commit in the Fixes: line below, before which the above debug printing checked and handled a NULL device pointer gracefully in DRM core. Cc: Jani Nikula Fixes: 529798bd786a ("drm/i915/mst: convert to struct intel_display") Closes: https://gitlab.freedesktop.org/drm/i915/kernel/-/issues/12799 Reviewed-by: Rodrigo Vivi Signed-off-by: Imre Deak Reviewed-by: Jani Nikula Link: https://patchwork.freedesktop.org/patch/msgid/20241118131044.1278028-1-imre.deak@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index df7edcfe885b..f058360a2641 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1727,6 +1727,16 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo intel_dp_init_modeset_retry_work(intel_connector); + /* + * TODO: The following drm_connector specific initialization belongs + * to DRM core, however it happens atm too late in + * drm_connector_init(). That function will also expose the connector + * to in-kernel users, so it can't be called until the connector is + * sufficiently initialized; init the device pointer used by the + * following DSC setup, until a fix moving this to DRM core. + */ + intel_connector->base.dev = mgr->dev; + intel_connector->dp.dsc_decompression_aux = drm_dp_mst_dsc_aux_for_port(port); intel_dp_mst_read_decompression_port_dsc_caps(intel_dp, intel_connector); intel_connector->dp.dsc_hblank_expansion_quirk = -- 2.50.1 From ca596b781a8081a14077f1e902b4ce43c1fd8fb2 Mon Sep 17 00:00:00 2001 From: Animesh Manna Date: Tue, 5 Nov 2024 16:09:16 +0530 Subject: [PATCH 11/16] drm/i915/psr: Disable psr1 if setup_time > vblank MIME-Version: 1.0 Content-Type: text/plain; charset=utf8 Content-Transfer-Encoding: 8bit Issue is seen when PSR enabled with setup frames and when try to disable PSR at SRDONACK State (0x1). PSR FSM is stuck at SRDONACK(0x1) for more than 5 seconds. Issue not seen with Setup frames disabled. Currently disable psr1 if setuptime > vblank to workaround the above issue. HSD: 16024594674 WA: 18037818876 v1: Initial version v2: Add debug log and some cosmetic changes. [Jouni, Jani, Nemesa] Signed-off-by: Animesh Manna Reviewed-by: Jouni Högander Link: https://patchwork.freedesktop.org/patch/msgid/20241105103916.1857731-1-animesh.manna@intel.com --- drivers/gpu/drm/i915/display/intel_psr.c | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/drivers/gpu/drm/i915/display/intel_psr.c b/drivers/gpu/drm/i915/display/intel_psr.c index 3c498b3ed175..15b70a1127d4 100644 --- a/drivers/gpu/drm/i915/display/intel_psr.c +++ b/drivers/gpu/drm/i915/display/intel_psr.c @@ -1637,6 +1637,15 @@ _panel_replay_compute_config(struct intel_dp *intel_dp, return true; } +static bool intel_psr_needs_wa_18037818876(struct intel_dp *intel_dp, + struct intel_crtc_state *crtc_state) +{ + struct intel_display *display = to_intel_display(intel_dp); + + return (DISPLAY_VER(display) == 20 && intel_dp->psr.entry_setup_frames > 0 && + !crtc_state->has_sel_update); +} + void intel_psr_compute_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) @@ -1689,6 +1698,13 @@ void intel_psr_compute_config(struct intel_dp *intel_dp, return; crtc_state->has_sel_update = intel_sel_update_config_valid(intel_dp, crtc_state); + + /* Wa_18037818876 */ + if (intel_psr_needs_wa_18037818876(intel_dp, crtc_state)) { + crtc_state->has_psr = false; + drm_dbg_kms(display->drm, + "PSR disabled to workaround PSR FSM hang issue\n"); + } } void intel_psr_get_config(struct intel_encoder *encoder, -- 2.50.1 From f635e7657e5bb80e1a7a9c3943a3daa71aefd88f Mon Sep 17 00:00:00 2001 From: Ankit Nautiyal Date: Wed, 13 Nov 2024 17:25:31 +0530 Subject: [PATCH 12/16] drm/i915/display/xe3lpd: Avoid setting YUV420_MODE in PIPE_MISC For Xe3_LPD the PIPE_MISC YUV420 Enable (bit 27), already implies enabling full blend YUV420 mode and YUV420 Mode (bit 26) is removed. Therefore, avoid setting YUV420 Mode for Xe3_LPD+ while programming PIPE_MISC for YCbCr420 output format. Bspec: 69749 Signed-off-by: Ankit Nautiyal Reviewed-by: Juha-Pekka Heikkila Link: https://patchwork.freedesktop.org/patch/msgid/20241113115531.3394962-1-ankit.k.nautiyal@intel.com --- drivers/gpu/drm/i915/display/intel_display.c | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_display.c b/drivers/gpu/drm/i915/display/intel_display.c index e790a2de5b3d..9db255bb1230 100644 --- a/drivers/gpu/drm/i915/display/intel_display.c +++ b/drivers/gpu/drm/i915/display/intel_display.c @@ -3137,9 +3137,14 @@ bdw_get_pipe_misc_output_format(struct intel_crtc *crtc) tmp = intel_de_read(dev_priv, PIPE_MISC(crtc->pipe)); if (tmp & PIPE_MISC_YUV420_ENABLE) { - /* We support 4:2:0 in full blend mode only */ - drm_WARN_ON(&dev_priv->drm, - (tmp & PIPE_MISC_YUV420_MODE_FULL_BLEND) == 0); + /* + * We support 4:2:0 in full blend mode only. + * For xe3_lpd+ this is implied in YUV420 Enable bit. + * Ensure the same for prior platforms in YUV420 Mode bit. + */ + if (DISPLAY_VER(dev_priv) < 30) + drm_WARN_ON(&dev_priv->drm, + (tmp & PIPE_MISC_YUV420_MODE_FULL_BLEND) == 0); return INTEL_OUTPUT_FORMAT_YCBCR420; } else if (tmp & PIPE_MISC_OUTPUT_COLORSPACE_YUV) { @@ -3388,8 +3393,8 @@ static void bdw_set_pipe_misc(struct intel_dsb *dsb, val |= PIPE_MISC_OUTPUT_COLORSPACE_YUV; if (crtc_state->output_format == INTEL_OUTPUT_FORMAT_YCBCR420) - val |= PIPE_MISC_YUV420_ENABLE | - PIPE_MISC_YUV420_MODE_FULL_BLEND; + val |= DISPLAY_VER(display) >= 30 ? PIPE_MISC_YUV420_ENABLE : + PIPE_MISC_YUV420_ENABLE | PIPE_MISC_YUV420_MODE_FULL_BLEND; if (DISPLAY_VER(dev_priv) >= 11 && is_hdr_mode(crtc_state)) val |= PIPE_MISC_HDR_MODE_PRECISION; -- 2.50.1 From 2b1245f3ec879a42394b6b3407da33a0aaaebc0c Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 20 Nov 2024 14:43:09 +0200 Subject: [PATCH 13/16] drm/i915/mst: pass intel_dp around in mst stream helpers All of the functions in question operate on the primary encoder, and more specifically the primary intel_dp, so pass it around instead of the encoder for less ambiguity. Suggested-by: Imre Deak Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/165ee8b723c42bcdeb3adf6a1b34ea09371e5d64.1732106557.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 26 ++++++++++----------- 1 file changed, 12 insertions(+), 14 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index f058360a2641..dab50a1ed15b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -179,16 +179,15 @@ static int intel_dp_mst_dsc_get_slice_count(const struct intel_connector *connec num_joined_pipes); } -static int mst_stream_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, +static int mst_stream_find_vcpi_slots_for_bpp(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, int max_bpp, int min_bpp, struct link_config_limits *limits, struct drm_connector_state *conn_state, int step, bool dsc) { - struct intel_display *display = to_intel_display(encoder); + struct intel_display *display = to_intel_display(intel_dp); struct drm_atomic_state *state = crtc_state->uapi.state; - struct intel_dp *intel_dp = to_primary_dp(encoder); struct drm_dp_mst_topology_state *mst_state; struct intel_connector *connector = to_intel_connector(conn_state->connector); @@ -331,7 +330,7 @@ static int mst_stream_find_vcpi_slots_for_bpp(struct intel_encoder *encoder, return slots; } -static int mst_stream_compute_link_config(struct intel_encoder *encoder, +static int mst_stream_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, struct link_config_limits *limits) @@ -342,7 +341,7 @@ static int mst_stream_compute_link_config(struct intel_encoder *encoder, * FIXME: allocate the BW according to link_bpp, which in the case of * YUV420 is only half of the pipe bpp value. */ - slots = mst_stream_find_vcpi_slots_for_bpp(encoder, crtc_state, + slots = mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, fxp_q4_to_int(limits->link.max_bpp_x16), fxp_q4_to_int(limits->link.min_bpp_x16), limits, @@ -354,12 +353,12 @@ static int mst_stream_compute_link_config(struct intel_encoder *encoder, return 0; } -static int mst_stream_dsc_compute_link_config(struct intel_encoder *encoder, +static int mst_stream_dsc_compute_link_config(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state, struct link_config_limits *limits) { - struct intel_display *display = to_intel_display(encoder); + struct intel_display *display = to_intel_display(intel_dp); struct intel_connector *connector = to_intel_connector(conn_state->connector); struct drm_i915_private *i915 = to_i915(connector->base.dev); int slots = -EINVAL; @@ -424,7 +423,7 @@ static int mst_stream_dsc_compute_link_config(struct intel_encoder *encoder, min_compressed_bpp = intel_dp_dsc_nearest_valid_bpp(i915, min_compressed_bpp, crtc_state->pipe_bpp); - slots = mst_stream_find_vcpi_slots_for_bpp(encoder, crtc_state, max_compressed_bpp, + slots = mst_stream_find_vcpi_slots_for_bpp(intel_dp, crtc_state, max_compressed_bpp, min_compressed_bpp, limits, conn_state, 1, true); @@ -434,12 +433,11 @@ static int mst_stream_dsc_compute_link_config(struct intel_encoder *encoder, return 0; } -static int mst_stream_update_slots(struct intel_encoder *encoder, +static int mst_stream_update_slots(struct intel_dp *intel_dp, struct intel_crtc_state *crtc_state, struct drm_connector_state *conn_state) { - struct intel_display *display = to_intel_display(encoder); - struct intel_dp *intel_dp = to_primary_dp(encoder); + struct intel_display *display = to_intel_display(intel_dp); struct drm_dp_mst_topology_mgr *mgr = &intel_dp->mst_mgr; struct drm_dp_mst_topology_state *topology_state; u8 link_coding_cap = intel_dp_is_uhbr(crtc_state) ? @@ -632,7 +630,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, pipe_config, false, &limits); if (!dsc_needed) { - ret = mst_stream_compute_link_config(encoder, pipe_config, + ret = mst_stream_compute_link_config(intel_dp, pipe_config, conn_state, &limits); if (ret == -EDEADLK) @@ -668,7 +666,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, */ drm_dbg_kms(display->drm, "Trying to find VCPI slots in DSC mode\n"); - ret = mst_stream_dsc_compute_link_config(encoder, pipe_config, + ret = mst_stream_dsc_compute_link_config(intel_dp, pipe_config, conn_state, &limits); if (ret < 0) return ret; @@ -681,7 +679,7 @@ static int mst_stream_compute_config(struct intel_encoder *encoder, if (ret) return ret; - ret = mst_stream_update_slots(encoder, pipe_config, conn_state); + ret = mst_stream_update_slots(intel_dp, pipe_config, conn_state); if (ret) return ret; -- 2.50.1 From fdb65ede8a45240552e867d5c17186d917d29147 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 20 Nov 2024 14:43:10 +0200 Subject: [PATCH 14/16] drm/i915/mst: unify MST connector function naming to mst_connector_* Similar to commit 5674e700d43e ("drm/i915/mst: change naming from fake encoders to MST stream encoders"), name all MST connector related functions to mst_connector_*. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/3d4814a94b97fcff88722e0effd2fb5893b256af.1732106557.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 63 +++++++++++---------- 1 file changed, 32 insertions(+), 31 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index dab50a1ed15b..56b2db02893d 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -888,8 +888,8 @@ static int mst_stream_compute_config_late(struct intel_encoder *encoder, * recomputation of the corresponding CRTC states. */ static int -intel_dp_mst_atomic_topology_check(struct intel_connector *connector, - struct intel_atomic_state *state) +mst_connector_atomic_topology_check(struct intel_connector *connector, + struct intel_atomic_state *state) { struct intel_display *display = to_intel_display(connector); struct drm_connector_list_iter connector_list_iter; @@ -937,8 +937,8 @@ intel_dp_mst_atomic_topology_check(struct intel_connector *connector, } static int -intel_dp_mst_atomic_check(struct drm_connector *connector, - struct drm_atomic_state *_state) +mst_connector_atomic_check(struct drm_connector *connector, + struct drm_atomic_state *_state) { struct intel_atomic_state *state = to_intel_atomic_state(_state); struct intel_connector *intel_connector = @@ -949,7 +949,7 @@ intel_dp_mst_atomic_check(struct drm_connector *connector, if (ret) return ret; - ret = intel_dp_mst_atomic_topology_check(intel_connector, state); + ret = mst_connector_atomic_topology_check(intel_connector, state); if (ret) return ret; @@ -1363,7 +1363,7 @@ static bool mst_stream_initial_fastset_check(struct intel_encoder *encoder, return intel_dp_initial_fastset_check(primary_encoder, crtc_state); } -static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector) +static int mst_connector_get_ddc_modes(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); struct drm_i915_private *i915 = to_i915(intel_connector->base.dev); @@ -1387,7 +1387,7 @@ static int intel_dp_mst_get_ddc_modes(struct drm_connector *connector) } static int -intel_dp_mst_connector_late_register(struct drm_connector *connector) +mst_connector_late_register(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); int ret; @@ -1406,7 +1406,7 @@ intel_dp_mst_connector_late_register(struct drm_connector *connector) } static void -intel_dp_mst_connector_early_unregister(struct drm_connector *connector) +mst_connector_early_unregister(struct drm_connector *connector) { struct intel_connector *intel_connector = to_intel_connector(connector); @@ -1415,27 +1415,27 @@ intel_dp_mst_connector_early_unregister(struct drm_connector *connector) intel_connector->port); } -static const struct drm_connector_funcs intel_dp_mst_connector_funcs = { +static const struct drm_connector_funcs mst_connector_funcs = { .fill_modes = drm_helper_probe_single_connector_modes, .atomic_get_property = intel_digital_connector_atomic_get_property, .atomic_set_property = intel_digital_connector_atomic_set_property, - .late_register = intel_dp_mst_connector_late_register, - .early_unregister = intel_dp_mst_connector_early_unregister, + .late_register = mst_connector_late_register, + .early_unregister = mst_connector_early_unregister, .destroy = intel_connector_destroy, .atomic_destroy_state = drm_atomic_helper_connector_destroy_state, .atomic_duplicate_state = intel_digital_connector_duplicate_state, }; -static int intel_dp_mst_get_modes(struct drm_connector *connector) +static int mst_connector_get_modes(struct drm_connector *connector) { - return intel_dp_mst_get_ddc_modes(connector); + return mst_connector_get_ddc_modes(connector); } static int -intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, - struct drm_display_mode *mode, - struct drm_modeset_acquire_ctx *ctx, - enum drm_mode_status *status) +mst_connector_mode_valid_ctx(struct drm_connector *connector, + struct drm_display_mode *mode, + struct drm_modeset_acquire_ctx *ctx, + enum drm_mode_status *status) { struct intel_display *display = to_intel_display(connector->dev); struct drm_i915_private *dev_priv = to_i915(connector->dev); @@ -1546,8 +1546,9 @@ intel_dp_mst_mode_valid_ctx(struct drm_connector *connector, return 0; } -static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *connector, - struct drm_atomic_state *state) +static struct drm_encoder * +mst_connector_atomic_best_encoder(struct drm_connector *connector, + struct drm_atomic_state *state) { struct drm_connector_state *connector_state = drm_atomic_get_new_connector_state(state, connector); @@ -1559,8 +1560,8 @@ static struct drm_encoder *intel_mst_atomic_best_encoder(struct drm_connector *c } static int -intel_dp_mst_detect(struct drm_connector *connector, - struct drm_modeset_acquire_ctx *ctx, bool force) +mst_connector_detect_ctx(struct drm_connector *connector, + struct drm_modeset_acquire_ctx *ctx, bool force) { struct intel_display *display = to_intel_display(connector->dev); struct drm_i915_private *i915 = to_i915(connector->dev); @@ -1582,12 +1583,12 @@ intel_dp_mst_detect(struct drm_connector *connector, intel_connector->port); } -static const struct drm_connector_helper_funcs intel_dp_mst_connector_helper_funcs = { - .get_modes = intel_dp_mst_get_modes, - .mode_valid_ctx = intel_dp_mst_mode_valid_ctx, - .atomic_best_encoder = intel_mst_atomic_best_encoder, - .atomic_check = intel_dp_mst_atomic_check, - .detect_ctx = intel_dp_mst_detect, +static const struct drm_connector_helper_funcs mst_connector_helper_funcs = { + .get_modes = mst_connector_get_modes, + .mode_valid_ctx = mst_connector_mode_valid_ctx, + .atomic_best_encoder = mst_connector_atomic_best_encoder, + .atomic_check = mst_connector_atomic_check, + .detect_ctx = mst_connector_detect_ctx, }; static void mst_stream_encoder_destroy(struct drm_encoder *encoder) @@ -1602,7 +1603,7 @@ static const struct drm_encoder_funcs mst_stream_encoder_funcs = { .destroy = mst_stream_encoder_destroy, }; -static bool intel_dp_mst_get_hw_state(struct intel_connector *connector) +static bool mst_connector_get_hw_state(struct intel_connector *connector) { if (intel_attached_encoder(connector) && connector->base.state->crtc) { enum pipe pipe; @@ -1717,7 +1718,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo if (!intel_connector) return NULL; - intel_connector->get_hw_state = intel_dp_mst_get_hw_state; + intel_connector->get_hw_state = mst_connector_get_hw_state; intel_connector->sync_state = intel_dp_connector_sync_state; intel_connector->mst_port = intel_dp; intel_connector->port = port; @@ -1741,7 +1742,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo detect_dsc_hblank_expansion_quirk(intel_connector); connector = &intel_connector->base; - ret = drm_connector_init(display->drm, connector, &intel_dp_mst_connector_funcs, + ret = drm_connector_init(display->drm, connector, &mst_connector_funcs, DRM_MODE_CONNECTOR_DisplayPort); if (ret) { drm_dp_mst_put_port_malloc(port); @@ -1749,7 +1750,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo return NULL; } - drm_connector_helper_add(connector, &intel_dp_mst_connector_helper_funcs); + drm_connector_helper_add(connector, &mst_connector_helper_funcs); for_each_pipe(display, pipe) { struct drm_encoder *enc = -- 2.50.1 From 81c6d5d83bc794c10366cab3da0534622c137a84 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 20 Nov 2024 14:43:11 +0200 Subject: [PATCH 15/16] drm/i915/mst: simplify mst_connector_get_hw_state() Use a variable for the encoder to simplify. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/eb8595ae36c6330cce1615059bd2c89a7db79668.1732106557.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index 56b2db02893d..b5e8db579e20 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1605,13 +1605,14 @@ static const struct drm_encoder_funcs mst_stream_encoder_funcs = { static bool mst_connector_get_hw_state(struct intel_connector *connector) { - if (intel_attached_encoder(connector) && connector->base.state->crtc) { - enum pipe pipe; - if (!intel_attached_encoder(connector)->get_hw_state(intel_attached_encoder(connector), &pipe)) - return false; - return true; - } - return false; + /* This is the MST stream encoder set in ->pre_enable, if any */ + struct intel_encoder *encoder = intel_attached_encoder(connector); + enum pipe pipe; + + if (!encoder || !connector->base.state->crtc) + return false; + + return encoder->get_hw_state(encoder, &pipe); } static int intel_dp_mst_add_properties(struct intel_dp *intel_dp, -- 2.50.1 From 5503f8112e52da6d964f0d9a70d810b0eb4d4ce8 Mon Sep 17 00:00:00 2001 From: Jani Nikula Date: Wed, 20 Nov 2024 14:43:12 +0200 Subject: [PATCH 16/16] drm/i915/mst: unify MST topology callback naming to mst_topology_* Make it easier to keep track of what belongs where. Reviewed-by: Imre Deak Link: https://patchwork.freedesktop.org/patch/msgid/e8efc8fddc3ca93e1256a1dad13bc4eca07c3382.1732106557.git.jani.nikula@intel.com Signed-off-by: Jani Nikula --- drivers/gpu/drm/i915/display/intel_dp_mst.c | 25 +++++++++++---------- 1 file changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c index b5e8db579e20..9dd8d2d9048b 100644 --- a/drivers/gpu/drm/i915/display/intel_dp_mst.c +++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c @@ -1615,9 +1615,9 @@ static bool mst_connector_get_hw_state(struct intel_connector *connector) return encoder->get_hw_state(encoder, &pipe); } -static int intel_dp_mst_add_properties(struct intel_dp *intel_dp, - struct drm_connector *connector, - const char *pathprop) +static int mst_topology_add_connector_properties(struct intel_dp *intel_dp, + struct drm_connector *connector, + const char *pathprop) { struct intel_display *display = to_intel_display(intel_dp); @@ -1703,9 +1703,10 @@ static bool detect_dsc_hblank_expansion_quirk(const struct intel_connector *conn return true; } -static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topology_mgr *mgr, - struct drm_dp_mst_port *port, - const char *pathprop) +static struct drm_connector * +mst_topology_add_connector(struct drm_dp_mst_topology_mgr *mgr, + struct drm_dp_mst_port *port, + const char *pathprop) { struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); struct intel_display *display = to_intel_display(intel_dp); @@ -1762,7 +1763,7 @@ static struct drm_connector *intel_dp_add_mst_connector(struct drm_dp_mst_topolo goto err; } - ret = intel_dp_mst_add_properties(intel_dp, connector, pathprop); + ret = mst_topology_add_connector_properties(intel_dp, connector, pathprop); if (ret) goto err; @@ -1779,16 +1780,16 @@ err: } static void -intel_dp_mst_poll_hpd_irq(struct drm_dp_mst_topology_mgr *mgr) +mst_topology_poll_hpd_irq(struct drm_dp_mst_topology_mgr *mgr) { struct intel_dp *intel_dp = container_of(mgr, struct intel_dp, mst_mgr); intel_hpd_trigger_irq(dp_to_dig_port(intel_dp)); } -static const struct drm_dp_mst_topology_cbs mst_cbs = { - .add_connector = intel_dp_add_mst_connector, - .poll_hpd_irq = intel_dp_mst_poll_hpd_irq, +static const struct drm_dp_mst_topology_cbs mst_topology_cbs = { + .add_connector = mst_topology_add_connector, + .poll_hpd_irq = mst_topology_poll_hpd_irq, }; /* Create a fake encoder for an individual MST stream */ @@ -1881,7 +1882,7 @@ intel_dp_mst_encoder_init(struct intel_digital_port *dig_port, int conn_base_id) if (DISPLAY_VER(display) < 11 && port == PORT_E) return 0; - intel_dp->mst_mgr.cbs = &mst_cbs; + intel_dp->mst_mgr.cbs = &mst_topology_cbs; /* create encoders */ mst_stream_encoders_create(dig_port); -- 2.50.1