Skip to content

Commit 31d886b

Browse files
Jocelyn FalempeMaarten Lankhorst
authored andcommitted
drm/i915/display: Add drm_panic support
This adds drm_panic support for a wide range of Intel GPU. I've tested it only on 4 laptops, Haswell (with 128MB of eDRAM), Comet Lake, Raptor Lake, and Lunar Lake. For hardware using DPT, it's not possible to disable tiling, as you will need to reconfigure the way the GPU is accessing the framebuffer, so this will be handled by the following patches. Signed-off-by: Jocelyn Falempe <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Maarten Lankhorst <[email protected]>
1 parent 75fb60e commit 31d886b

File tree

1 file changed

+82
-1
lines changed

1 file changed

+82
-1
lines changed

drivers/gpu/drm/i915/display/intel_plane.c

Lines changed: 82 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,25 +33,30 @@
3333

3434
#include <linux/dma-fence-chain.h>
3535
#include <linux/dma-resv.h>
36+
#include <linux/iosys-map.h>
3637

3738
#include <drm/drm_atomic_helper.h>
3839
#include <drm/drm_blend.h>
40+
#include <drm/drm_cache.h>
3941
#include <drm/drm_damage_helper.h>
4042
#include <drm/drm_fourcc.h>
4143
#include <drm/drm_gem.h>
4244
#include <drm/drm_gem_atomic_helper.h>
45+
#include <drm/drm_panic.h>
4346

4447
#include "gem/i915_gem_object.h"
4548
#include "i915_scheduler_types.h"
4649
#include "i915_vma.h"
4750
#include "i9xx_plane_regs.h"
51+
#include "intel_bo.h"
4852
#include "intel_cdclk.h"
4953
#include "intel_cursor.h"
5054
#include "intel_display_rps.h"
5155
#include "intel_display_trace.h"
5256
#include "intel_display_types.h"
5357
#include "intel_fb.h"
5458
#include "intel_fb_pin.h"
59+
#include "intel_fbdev.h"
5560
#include "intel_plane.h"
5661
#include "skl_scaler.h"
5762
#include "skl_universal_plane.h"
@@ -1267,14 +1272,90 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
12671272
intel_plane_unpin_fb(old_plane_state);
12681273
}
12691274

1275+
static void intel_panic_flush(struct drm_plane *plane)
1276+
{
1277+
struct intel_plane_state *plane_state = to_intel_plane_state(plane->state);
1278+
struct intel_plane *iplane = to_intel_plane(plane);
1279+
struct intel_display *display = to_intel_display(iplane);
1280+
struct drm_framebuffer *fb = plane_state->hw.fb;
1281+
struct intel_framebuffer *intel_fb = to_intel_framebuffer(fb);
1282+
1283+
intel_bo_panic_finish(intel_fb);
1284+
1285+
/* Flush the cache and don't disable tiling if it's the fbdev framebuffer.*/
1286+
if (intel_fb == intel_fbdev_framebuffer(display->fbdev.fbdev)) {
1287+
struct iosys_map map;
1288+
1289+
intel_fbdev_get_map(display->fbdev.fbdev, &map);
1290+
drm_clflush_virt_range(map.vaddr, fb->pitches[0] * fb->height);
1291+
return;
1292+
}
1293+
1294+
if (fb->modifier && iplane->disable_tiling)
1295+
iplane->disable_tiling(iplane);
1296+
}
1297+
1298+
static int intel_get_scanout_buffer(struct drm_plane *plane,
1299+
struct drm_scanout_buffer *sb)
1300+
{
1301+
struct intel_plane_state *plane_state;
1302+
struct drm_gem_object *obj;
1303+
struct drm_framebuffer *fb;
1304+
struct intel_framebuffer *intel_fb;
1305+
struct intel_display *display = to_intel_display(plane->dev);
1306+
1307+
if (!plane->state || !plane->state->fb || !plane->state->visible)
1308+
return -ENODEV;
1309+
1310+
plane_state = to_intel_plane_state(plane->state);
1311+
fb = plane_state->hw.fb;
1312+
intel_fb = to_intel_framebuffer(fb);
1313+
1314+
obj = intel_fb_bo(fb);
1315+
if (!obj)
1316+
return -ENODEV;
1317+
1318+
if (intel_fb == intel_fbdev_framebuffer(display->fbdev.fbdev)) {
1319+
intel_fbdev_get_map(display->fbdev.fbdev, &sb->map[0]);
1320+
} else {
1321+
int ret;
1322+
/* Can't disable tiling if DPT is in use */
1323+
if (intel_fb_uses_dpt(fb))
1324+
return -EOPNOTSUPP;
1325+
sb->private = intel_fb;
1326+
ret = intel_bo_panic_setup(sb);
1327+
if (ret)
1328+
return ret;
1329+
}
1330+
sb->width = fb->width;
1331+
sb->height = fb->height;
1332+
/* Use the generic linear format, because tiling, RC, CCS, CC
1333+
* will be disabled in disable_tiling()
1334+
*/
1335+
sb->format = drm_format_info(fb->format->format);
1336+
sb->pitch[0] = fb->pitches[0];
1337+
1338+
return 0;
1339+
}
1340+
12701341
static const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
12711342
.prepare_fb = intel_prepare_plane_fb,
12721343
.cleanup_fb = intel_cleanup_plane_fb,
12731344
};
12741345

1346+
static const struct drm_plane_helper_funcs intel_primary_plane_helper_funcs = {
1347+
.prepare_fb = intel_prepare_plane_fb,
1348+
.cleanup_fb = intel_cleanup_plane_fb,
1349+
.get_scanout_buffer = intel_get_scanout_buffer,
1350+
.panic_flush = intel_panic_flush,
1351+
};
1352+
12751353
void intel_plane_helper_add(struct intel_plane *plane)
12761354
{
1277-
drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
1355+
if (plane->base.type == DRM_PLANE_TYPE_PRIMARY)
1356+
drm_plane_helper_add(&plane->base, &intel_primary_plane_helper_funcs);
1357+
else
1358+
drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs);
12781359
}
12791360

12801361
void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state,

0 commit comments

Comments
 (0)