|
33 | 33 |
|
34 | 34 | #include <linux/dma-fence-chain.h>
|
35 | 35 | #include <linux/dma-resv.h>
|
| 36 | +#include <linux/iosys-map.h> |
36 | 37 |
|
37 | 38 | #include <drm/drm_atomic_helper.h>
|
38 | 39 | #include <drm/drm_blend.h>
|
| 40 | +#include <drm/drm_cache.h> |
39 | 41 | #include <drm/drm_damage_helper.h>
|
40 | 42 | #include <drm/drm_fourcc.h>
|
41 | 43 | #include <drm/drm_gem.h>
|
42 | 44 | #include <drm/drm_gem_atomic_helper.h>
|
| 45 | +#include <drm/drm_panic.h> |
43 | 46 |
|
44 | 47 | #include "gem/i915_gem_object.h"
|
45 | 48 | #include "i915_scheduler_types.h"
|
46 | 49 | #include "i915_vma.h"
|
47 | 50 | #include "i9xx_plane_regs.h"
|
| 51 | +#include "intel_bo.h" |
48 | 52 | #include "intel_cdclk.h"
|
49 | 53 | #include "intel_cursor.h"
|
50 | 54 | #include "intel_display_rps.h"
|
51 | 55 | #include "intel_display_trace.h"
|
52 | 56 | #include "intel_display_types.h"
|
53 | 57 | #include "intel_fb.h"
|
54 | 58 | #include "intel_fb_pin.h"
|
| 59 | +#include "intel_fbdev.h" |
55 | 60 | #include "intel_plane.h"
|
56 | 61 | #include "skl_scaler.h"
|
57 | 62 | #include "skl_universal_plane.h"
|
@@ -1267,14 +1272,90 @@ intel_cleanup_plane_fb(struct drm_plane *plane,
|
1267 | 1272 | intel_plane_unpin_fb(old_plane_state);
|
1268 | 1273 | }
|
1269 | 1274 |
|
| 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 | + |
1270 | 1341 | static const struct drm_plane_helper_funcs intel_plane_helper_funcs = {
|
1271 | 1342 | .prepare_fb = intel_prepare_plane_fb,
|
1272 | 1343 | .cleanup_fb = intel_cleanup_plane_fb,
|
1273 | 1344 | };
|
1274 | 1345 |
|
| 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 | + |
1275 | 1353 | void intel_plane_helper_add(struct intel_plane *plane)
|
1276 | 1354 | {
|
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); |
1278 | 1359 | }
|
1279 | 1360 |
|
1280 | 1361 | void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state,
|
|
0 commit comments