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
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
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
© 2016 - 2024 Red Hat, Inc.