[PATCH 5/5] drm/i915: Add drm_panic support

Jocelyn Falempe posted 5 patches 3 weeks, 5 days ago
There is a newer version of this series
[PATCH 5/5] drm/i915: Add drm_panic support
Posted by Jocelyn Falempe 3 weeks, 5 days ago
This adds drm_panic support for a wide range of Intel GPU. I've
tested it only on 3 laptops, haswell (with 128MB of eDRAM),
cometlake and alderlake.

 * DPT: if I disable tiling on a framebuffer using DPT, then it
   displays some other memory location. As DPT is enabled only for
   tiled framebuffer, there might be some hardware limitations.
 * fbdev: On my haswell laptop, the fbdev framebuffer is configured
   with tiling enabled, but really it's linear, because fbcon don't
   know about tiling, and the panic screen is perfect when it's drawn
   as linear.

Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
---
 .../gpu/drm/i915/display/intel_atomic_plane.c | 98 ++++++++++++++++++-
 1 file changed, 97 insertions(+), 1 deletion(-)

diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
index b7e462075ded3..43dac5538a648 100644
--- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c
+++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c
@@ -33,13 +33,17 @@
 
 #include <linux/dma-fence-chain.h>
 #include <linux/dma-resv.h>
+#include <linux/iosys-map.h>
 
 #include <drm/drm_atomic_helper.h>
 #include <drm/drm_blend.h>
+#include <drm/drm_cache.h>
 #include <drm/drm_fourcc.h>
 #include <drm/drm_gem.h>
 #include <drm/drm_gem_atomic_helper.h>
+#include <drm/drm_panic.h>
 
+#include "gem/i915_gem_object.h"
 #include "i915_config.h"
 #include "i9xx_plane_regs.h"
 #include "intel_atomic_plane.h"
@@ -50,6 +54,7 @@
 #include "intel_display_types.h"
 #include "intel_fb.h"
 #include "intel_fb_pin.h"
+#include "intel_fbdev.h"
 #include "skl_scaler.h"
 #include "skl_watermark.h"
 
@@ -1198,14 +1203,105 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
 	intel_plane_unpin_fb(old_plane_state);
 }
 
+/* Only used by drm_panic get_scanout_buffer() and panic_flush(), so it is
+ * protected by the drm panic spinlock
+ */
+static struct iosys_map panic_map;
+
+static void intel_panic_flush(struct drm_plane *plane)
+{
+	struct intel_plane_state *plane_state = to_intel_plane_state(plane->state);
+	struct drm_i915_private *dev_priv = to_i915(plane->dev);
+	struct drm_framebuffer *fb = plane_state->hw.fb;
+	struct intel_plane *iplane = to_intel_plane(plane);
+
+	/* Force a cache flush, otherwise the new pixels won't show up */
+	drm_clflush_virt_range(panic_map.vaddr, fb->height * fb->pitches[0]);
+
+	/* Don't disable tiling if it's the fbdev framebuffer.*/
+	if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev))
+		return;
+
+	if (fb->modifier && iplane->disable_tiling)
+		iplane->disable_tiling(iplane);
+}
+
+static int intel_get_scanout_buffer(struct drm_plane *plane,
+				    struct drm_scanout_buffer *sb)
+{
+	struct intel_plane_state *plane_state;
+	struct drm_gem_object *gem_obj;
+	struct drm_i915_gem_object *obj;
+	struct drm_framebuffer *fb;
+	struct drm_i915_private *dev_priv = to_i915(plane->dev);
+	void *ptr;
+	enum i915_map_type has_type;
+
+	if (!plane->state || !plane->state->fb || !plane->state->visible)
+		return -ENODEV;
+
+	plane_state = to_intel_plane_state(plane->state);
+	fb = plane_state->hw.fb;
+	gem_obj = intel_fb_bo(fb);
+	if (!gem_obj)
+		return -ENODEV;
+
+	obj = to_intel_bo(gem_obj);
+
+	if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev)) {
+		ptr = intel_fbdev_getvaddr(dev_priv->display.fbdev.fbdev);
+		if (!ptr)
+			return -ENOMEM;
+	} else {
+		/* can't disable tiling if DPT is in use */
+		if (fb->modifier && HAS_DPT(dev_priv))
+			return -EOPNOTSUPP;
+
+		/* Taken from i915_gem_object_pin_map() */
+		ptr = page_unpack_bits(obj->mm.mapping, &has_type);
+		if (!ptr) {
+			if (i915_gem_object_has_struct_page(obj))
+				ptr = i915_gem_object_map_page(obj, I915_MAP_WB);
+			else
+				ptr = i915_gem_object_map_pfn(obj, I915_MAP_WB);
+			if (IS_ERR(ptr))
+				return -ENOMEM;
+		}
+	}
+
+	if (i915_gem_object_has_iomem(obj))
+		iosys_map_set_vaddr_iomem(&panic_map, ptr);
+	else
+		iosys_map_set_vaddr(&panic_map, ptr);
+
+	sb->map[0] = panic_map;
+	sb->width = fb->width;
+	sb->height = fb->height;
+	sb->format = fb->format;
+	sb->pitch[0] = fb->pitches[0];
+
+	return 0;
+}
+
 static const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
 	.prepare_fb = intel_prepare_plane_fb,
 	.cleanup_fb = intel_cleanup_plane_fb,
 };
 
+
+static const struct drm_plane_helper_funcs intel_primary_plane_helper_funcs = {
+	.prepare_fb = intel_prepare_plane_fb,
+	.cleanup_fb = intel_cleanup_plane_fb,
+	.get_scanout_buffer = intel_get_scanout_buffer,
+	.panic_flush = intel_panic_flush,
+};
+
 void intel_plane_helper_add(struct intel_plane *plane)
 {
-	drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
+	if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
+		drm_plane_helper_add(&plane->base, &intel_primary_plane_helper_funcs);
+	else
+		drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
 }
 
 void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state,
-- 
2.47.0
Re: [PATCH 5/5] drm/i915: Add drm_panic support
Posted by kernel test robot 3 weeks, 5 days ago
Hi Jocelyn,

kernel test robot noticed the following build warnings:

[auto build test WARNING on 44cff6c5b0b17a78bc0b30372bcd816cf6dd282a]

url:    https://github.com/intel-lab-lkp/linux/commits/Jocelyn-Falempe/drm-i915-fbdev-Add-intel_fbdev_getvaddr/20241130-002536
base:   44cff6c5b0b17a78bc0b30372bcd816cf6dd282a
patch link:    https://lore.kernel.org/r/20241129162232.7594-6-jfalempe%40redhat.com
patch subject: [PATCH 5/5] drm/i915: Add drm_panic support
config: i386-randconfig-061-20241130 (https://download.01.org/0day-ci/archive/20241130/202411302022.wlwTKMBh-lkp@intel.com/config)
compiler: clang version 19.1.3 (https://github.com/llvm/llvm-project ab51eccf88f5321e7c60591c5546b254b6afab99)
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241130/202411302022.wlwTKMBh-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411302022.wlwTKMBh-lkp@intel.com/

sparse warnings: (new ones prefixed by >>)
>> drivers/gpu/drm/i915/display/intel_atomic_plane.c:1273:55: sparse: sparse: incorrect type in argument 2 (different address spaces) @@     expected void [noderef] __iomem *vaddr_iomem @@     got void *[assigned] ptr @@
   drivers/gpu/drm/i915/display/intel_atomic_plane.c:1273:55: sparse:     expected void [noderef] __iomem *vaddr_iomem
   drivers/gpu/drm/i915/display/intel_atomic_plane.c:1273:55: sparse:     got void *[assigned] ptr

vim +1273 drivers/gpu/drm/i915/display/intel_atomic_plane.c

  1228	
  1229	static int intel_get_scanout_buffer(struct drm_plane *plane,
  1230					    struct drm_scanout_buffer *sb)
  1231	{
  1232		struct intel_plane_state *plane_state;
  1233		struct drm_gem_object *gem_obj;
  1234		struct drm_i915_gem_object *obj;
  1235		struct drm_framebuffer *fb;
  1236		struct drm_i915_private *dev_priv = to_i915(plane->dev);
  1237		void *ptr;
  1238		enum i915_map_type has_type;
  1239	
  1240		if (!plane->state || !plane->state->fb || !plane->state->visible)
  1241			return -ENODEV;
  1242	
  1243		plane_state = to_intel_plane_state(plane->state);
  1244		fb = plane_state->hw.fb;
  1245		gem_obj = intel_fb_bo(fb);
  1246		if (!gem_obj)
  1247			return -ENODEV;
  1248	
  1249		obj = to_intel_bo(gem_obj);
  1250	
  1251		if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev)) {
  1252			ptr = intel_fbdev_getvaddr(dev_priv->display.fbdev.fbdev);
  1253			if (!ptr)
  1254				return -ENOMEM;
  1255		} else {
  1256			/* can't disable tiling if DPT is in use */
  1257			if (fb->modifier && HAS_DPT(dev_priv))
  1258				return -EOPNOTSUPP;
  1259	
  1260			/* Taken from i915_gem_object_pin_map() */
  1261			ptr = page_unpack_bits(obj->mm.mapping, &has_type);
  1262			if (!ptr) {
  1263				if (i915_gem_object_has_struct_page(obj))
  1264					ptr = i915_gem_object_map_page(obj, I915_MAP_WB);
  1265				else
  1266					ptr = i915_gem_object_map_pfn(obj, I915_MAP_WB);
  1267				if (IS_ERR(ptr))
  1268					return -ENOMEM;
  1269			}
  1270		}
  1271	
  1272		if (i915_gem_object_has_iomem(obj))
> 1273			iosys_map_set_vaddr_iomem(&panic_map, ptr);
  1274		else
  1275			iosys_map_set_vaddr(&panic_map, ptr);
  1276	
  1277		sb->map[0] = panic_map;
  1278		sb->width = fb->width;
  1279		sb->height = fb->height;
  1280		sb->format = fb->format;
  1281		sb->pitch[0] = fb->pitches[0];
  1282	
  1283		return 0;
  1284	}
  1285	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki
Re: [PATCH 5/5] drm/i915: Add drm_panic support
Posted by kernel test robot 3 weeks, 5 days ago
Hi Jocelyn,

kernel test robot noticed the following build errors:

[auto build test ERROR on 44cff6c5b0b17a78bc0b30372bcd816cf6dd282a]

url:    https://github.com/intel-lab-lkp/linux/commits/Jocelyn-Falempe/drm-i915-fbdev-Add-intel_fbdev_getvaddr/20241130-002536
base:   44cff6c5b0b17a78bc0b30372bcd816cf6dd282a
patch link:    https://lore.kernel.org/r/20241129162232.7594-6-jfalempe%40redhat.com
patch subject: [PATCH 5/5] drm/i915: Add drm_panic support
config: i386-buildonly-randconfig-003-20241130 (https://download.01.org/0day-ci/archive/20241130/202411300629.WmnBjFIu-lkp@intel.com/config)
compiler: gcc-12 (Debian 12.2.0-14) 12.2.0
reproduce (this is a W=1 build): (https://download.01.org/0day-ci/archive/20241130/202411300629.WmnBjFIu-lkp@intel.com/reproduce)

If you fix the issue in a separate patch/commit (i.e. not just a new version of
the same patch/commit), kindly add following tags
| Reported-by: kernel test robot <lkp@intel.com>
| Closes: https://lore.kernel.org/oe-kbuild-all/202411300629.WmnBjFIu-lkp@intel.com/

All errors (new ones prefixed by >>):

>> drivers/gpu/drm/i915/display/intel_atomic_plane.c:46:10: fatal error: gem/i915_gem_object.h: No such file or directory
      46 | #include "gem/i915_gem_object.h"
         |          ^~~~~~~~~~~~~~~~~~~~~~~
   compilation terminated.


vim +46 drivers/gpu/drm/i915/display/intel_atomic_plane.c

    45	
  > 46	#include "gem/i915_gem_object.h"
    47	#include "i915_config.h"
    48	#include "i9xx_plane_regs.h"
    49	#include "intel_atomic_plane.h"
    50	#include "intel_cdclk.h"
    51	#include "intel_cursor.h"
    52	#include "intel_display_rps.h"
    53	#include "intel_display_trace.h"
    54	#include "intel_display_types.h"
    55	#include "intel_fb.h"
    56	#include "intel_fb_pin.h"
    57	#include "intel_fbdev.h"
    58	#include "skl_scaler.h"
    59	#include "skl_watermark.h"
    60	

-- 
0-DAY CI Kernel Test Service
https://github.com/intel/lkp-tests/wiki