1 | This is a first draft of drm_panic support for i915. | 1 | This is a draft of drm_panic support for i915. |
---|---|---|---|
2 | 2 | ||
3 | I've tested it on the 3 intel laptops I have at my disposal. | 3 | I've tested it on the 4 intel laptops I have at my disposal. |
4 | one Haswell with 128MB of eDRAM, one Cometlake and one Alderlake. | 4 | * Haswell with 128MB of eDRAM. |
5 | * Comet Lake i7-10850H | ||
6 | * Raptor Lake i7-1370P (with DPT, and Y-tiling). | ||
7 | * Lunar Lake Ultra 5 228V (with DPT, and 4-tiling, and using the Xe driver. | ||
5 | 8 | ||
6 | I tested panic in both fbdev console and gnome desktop. | 9 | I tested panic in both fbdev console and gnome desktop. |
7 | 10 | ||
8 | I still have an issue with Alderlake, and it doesn't work when in gnome desktop. | ||
9 | If I disable tiling on a framebuffer using DPT, then it displays some other memory location. | ||
10 | As DPT is enabled only for tiled framebuffer, there might be some hardware limitations? | ||
11 | I think it can be worked around by drawing the image tiled, (like what I've done on nouveau https://patchwork.freedesktop.org/series/133963/), but maybe there is another way? | ||
12 | |||
13 | Best regards, | 11 | Best regards, |
14 | 12 | ||
15 | Jocelyn Falempe (5): | 13 | v2: |
16 | drm/i915/fbdev: Add intel_fbdev_getvaddr() | 14 | * Add the proper abstractions to build also for Xe. |
15 | * Fix dim checkpatch issues. | ||
16 | |||
17 | v3: | ||
18 | * Add support for Y-tiled framebuffer when DPT is enabled. | ||
19 | |||
20 | v4: | ||
21 | * Add support for Xe driver, which shares most of the code. | ||
22 | * Add support for 4-tiled framebuffer found in newest GPU. | ||
23 | |||
24 | v5: | ||
25 | * Rebase on top of git@gitlab.freedesktop.org:drm/i915/kernel.git drm-intel-next | ||
26 | * Use struct intel_display instead of drm_i915_private. | ||
27 | * Use iosys_map for intel_bo_panic_map(). | ||
28 | |||
29 | v6: | ||
30 | * Rebase on top of git@gitlab.freedesktop.org:drm/i915/kernel.git drm-intel-next | ||
31 | * Use struct intel_display instead of drm_i915_private for intel_atomic_plane.c | ||
32 | |||
33 | Jocelyn Falempe (8): | ||
34 | drm/i915/fbdev: Add intel_fbdev_get_map() | ||
17 | drm/i915/display/i9xx: Add a disable_tiling() for i9xx planes | 35 | drm/i915/display/i9xx: Add a disable_tiling() for i9xx planes |
18 | drm/i915/display: Add a disable_tiling() for skl planes | 36 | drm/i915/display: Add a disable_tiling() for skl planes |
19 | drm/i915/gem: export i915_gem_object_map_page/pfn | 37 | drm/i915/gem: Add i915_gem_object_panic_map() |
20 | drm/i915: Add drm_panic support | 38 | drm/i915/display: Add drm_panic support |
39 | drm/i915/display: Flush the front buffer in panic handler | ||
40 | drm/i915/display: Add drm_panic support for Y-tiling with DPT | ||
41 | drm/i915/display: Add drm_panic support for 4-tiling with DPT | ||
21 | 42 | ||
22 | drivers/gpu/drm/i915/display/i9xx_plane.c | 24 +++++ | 43 | drivers/gpu/drm/i915/display/i9xx_plane.c | 23 +++ |
23 | .../gpu/drm/i915/display/intel_atomic_plane.c | 98 ++++++++++++++++++- | 44 | .../gpu/drm/i915/display/intel_atomic_plane.c | 169 +++++++++++++++++- |
24 | .../drm/i915/display/intel_display_types.h | 2 + | 45 | drivers/gpu/drm/i915/display/intel_bo.c | 5 + |
25 | drivers/gpu/drm/i915/display/intel_fbdev.c | 5 + | 46 | drivers/gpu/drm/i915/display/intel_bo.h | 1 + |
26 | drivers/gpu/drm/i915/display/intel_fbdev.h | 5 + | 47 | .../drm/i915/display/intel_display_types.h | 2 + |
27 | .../drm/i915/display/skl_universal_plane.c | 20 ++++ | 48 | drivers/gpu/drm/i915/display/intel_fb_pin.c | 5 + |
28 | drivers/gpu/drm/i915/gem/i915_gem_object.h | 5 + | 49 | drivers/gpu/drm/i915/display/intel_fb_pin.h | 2 + |
29 | drivers/gpu/drm/i915/gem/i915_gem_pages.c | 4 +- | 50 | drivers/gpu/drm/i915/display/intel_fbdev.c | 5 + |
30 | 8 files changed, 160 insertions(+), 3 deletions(-) | 51 | drivers/gpu/drm/i915/display/intel_fbdev.h | 6 +- |
52 | .../drm/i915/display/skl_universal_plane.c | 27 +++ | ||
53 | drivers/gpu/drm/i915/gem/i915_gem_object.h | 2 + | ||
54 | drivers/gpu/drm/i915/gem/i915_gem_pages.c | 29 +++ | ||
55 | drivers/gpu/drm/i915/i915_vma.h | 5 + | ||
56 | drivers/gpu/drm/xe/display/intel_bo.c | 10 ++ | ||
57 | drivers/gpu/drm/xe/display/xe_fb_pin.c | 5 + | ||
58 | 15 files changed, 294 insertions(+), 2 deletions(-) | ||
31 | 59 | ||
32 | 60 | ||
33 | base-commit: 44cff6c5b0b17a78bc0b30372bcd816cf6dd282a | 61 | base-commit: 010363c4618920838ca8777fdabd46871d289bf9 |
34 | -- | 62 | -- |
35 | 2.47.0 | 63 | 2.49.0 | diff view generated by jsdifflib |
1 | The vaddr of the fbdev framebuffer is private to the struct | 1 | The vaddr of the fbdev framebuffer is private to the struct |
---|---|---|---|
2 | intel_fbdev, so this function is needed to access it for drm_panic. | 2 | intel_fbdev, so this function is needed to access it for drm_panic. |
3 | Also the struct i915_vma is different between i915 and xe, so it | ||
4 | requires a few functions to access fbdev->vma->iomap. | ||
3 | 5 | ||
4 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> | 6 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> |
5 | --- | 7 | --- |
6 | drivers/gpu/drm/i915/display/intel_fbdev.c | 5 +++++ | ||
7 | drivers/gpu/drm/i915/display/intel_fbdev.h | 5 +++++ | ||
8 | 2 files changed, 10 insertions(+) | ||
9 | 8 | ||
9 | v2: | ||
10 | * Add intel_fb_get_vaddr() and i915_vma_get_iomap() to build with Xe driver. | ||
11 | |||
12 | v4: | ||
13 | * rename to get_map(), and return the struct iosys_map mapping. | ||
14 | * implement the Xe variant. | ||
15 | |||
16 | drivers/gpu/drm/i915/display/intel_fb_pin.c | 5 +++++ | ||
17 | drivers/gpu/drm/i915/display/intel_fb_pin.h | 2 ++ | ||
18 | drivers/gpu/drm/i915/display/intel_fbdev.c | 5 +++++ | ||
19 | drivers/gpu/drm/i915/display/intel_fbdev.h | 6 +++++- | ||
20 | drivers/gpu/drm/i915/i915_vma.h | 5 +++++ | ||
21 | drivers/gpu/drm/xe/display/xe_fb_pin.c | 5 +++++ | ||
22 | 6 files changed, 27 insertions(+), 1 deletion(-) | ||
23 | |||
24 | diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.c b/drivers/gpu/drm/i915/display/intel_fb_pin.c | ||
25 | index XXXXXXX..XXXXXXX 100644 | ||
26 | --- a/drivers/gpu/drm/i915/display/intel_fb_pin.c | ||
27 | +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.c | ||
28 | @@ -XXX,XX +XXX,XX @@ void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state) | ||
29 | intel_dpt_unpin_from_ggtt(fb->dpt_vm); | ||
30 | } | ||
31 | } | ||
32 | + | ||
33 | +void intel_fb_get_map(struct i915_vma *vma, struct iosys_map *map) | ||
34 | +{ | ||
35 | + iosys_map_set_vaddr_iomem(map, i915_vma_get_iomap(vma)); | ||
36 | +} | ||
37 | diff --git a/drivers/gpu/drm/i915/display/intel_fb_pin.h b/drivers/gpu/drm/i915/display/intel_fb_pin.h | ||
38 | index XXXXXXX..XXXXXXX 100644 | ||
39 | --- a/drivers/gpu/drm/i915/display/intel_fb_pin.h | ||
40 | +++ b/drivers/gpu/drm/i915/display/intel_fb_pin.h | ||
41 | @@ -XXX,XX +XXX,XX @@ struct drm_framebuffer; | ||
42 | struct i915_vma; | ||
43 | struct intel_plane_state; | ||
44 | struct i915_gtt_view; | ||
45 | +struct iosys_map; | ||
46 | |||
47 | struct i915_vma * | ||
48 | intel_fb_pin_to_ggtt(const struct drm_framebuffer *fb, | ||
49 | @@ -XXX,XX +XXX,XX @@ void intel_fb_unpin_vma(struct i915_vma *vma, unsigned long flags); | ||
50 | int intel_plane_pin_fb(struct intel_plane_state *new_plane_state, | ||
51 | const struct intel_plane_state *old_plane_state); | ||
52 | void intel_plane_unpin_fb(struct intel_plane_state *old_plane_state); | ||
53 | +void intel_fb_get_map(struct i915_vma *vma, struct iosys_map *map); | ||
54 | |||
55 | #endif | ||
10 | diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c | 56 | diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.c b/drivers/gpu/drm/i915/display/intel_fbdev.c |
11 | index XXXXXXX..XXXXXXX 100644 | 57 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/drivers/gpu/drm/i915/display/intel_fbdev.c | 58 | --- a/drivers/gpu/drm/i915/display/intel_fbdev.c |
13 | +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c | 59 | +++ b/drivers/gpu/drm/i915/display/intel_fbdev.c |
14 | @@ -XXX,XX +XXX,XX @@ struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev) | 60 | @@ -XXX,XX +XXX,XX @@ struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev) |
15 | 61 | { | |
16 | return to_intel_framebuffer(fbdev->helper.fb); | 62 | return fbdev ? fbdev->vma : NULL; |
17 | } | 63 | } |
18 | + | 64 | + |
19 | +void *intel_fbdev_getvaddr(struct intel_fbdev *fbdev) | 65 | +void intel_fbdev_get_map(struct intel_fbdev *fbdev, struct iosys_map *map) |
20 | +{ | 66 | +{ |
21 | + return READ_ONCE(fbdev->vma->iomap); | 67 | + intel_fb_get_map(fbdev->vma, map); |
22 | +} | 68 | +} |
23 | diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h | 69 | diff --git a/drivers/gpu/drm/i915/display/intel_fbdev.h b/drivers/gpu/drm/i915/display/intel_fbdev.h |
24 | index XXXXXXX..XXXXXXX 100644 | 70 | index XXXXXXX..XXXXXXX 100644 |
25 | --- a/drivers/gpu/drm/i915/display/intel_fbdev.h | 71 | --- a/drivers/gpu/drm/i915/display/intel_fbdev.h |
26 | +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h | 72 | +++ b/drivers/gpu/drm/i915/display/intel_fbdev.h |
27 | @@ -XXX,XX +XXX,XX @@ struct intel_framebuffer; | 73 | @@ -XXX,XX +XXX,XX @@ struct drm_fb_helper_surface_size; |
74 | struct drm_i915_private; | ||
75 | struct intel_fbdev; | ||
76 | struct intel_framebuffer; | ||
77 | +struct iosys_map; | ||
78 | |||
79 | #ifdef CONFIG_DRM_FBDEV_EMULATION | ||
80 | int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, | ||
81 | @@ -XXX,XX +XXX,XX @@ int intel_fbdev_driver_fbdev_probe(struct drm_fb_helper *helper, | ||
28 | void intel_fbdev_setup(struct drm_i915_private *dev_priv); | 82 | void intel_fbdev_setup(struct drm_i915_private *dev_priv); |
29 | void intel_fbdev_set_suspend(struct drm_device *dev, int state, bool synchronous); | ||
30 | struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); | 83 | struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbdev *fbdev); |
31 | +void *intel_fbdev_getvaddr(struct intel_fbdev *fbdev); | 84 | struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev); |
85 | - | ||
86 | +void intel_fbdev_get_map(struct intel_fbdev *fbdev, struct iosys_map *map); | ||
32 | #else | 87 | #else |
33 | static inline void intel_fbdev_setup(struct drm_i915_private *dev_priv) | 88 | #define INTEL_FBDEV_DRIVER_OPS \ |
34 | { | 89 | .fbdev_probe = NULL |
35 | @@ -XXX,XX +XXX,XX @@ static inline struct intel_framebuffer *intel_fbdev_framebuffer(struct intel_fbd | 90 | @@ -XXX,XX +XXX,XX @@ static inline struct i915_vma *intel_fbdev_vma_pointer(struct intel_fbdev *fbdev |
36 | { | ||
37 | return NULL; | 91 | return NULL; |
38 | } | 92 | } |
39 | +static inline void *intel_fbdev_getvaddr(struct intel_fbdev *fbdev) | 93 | |
94 | +static inline void intel_fbdev_get_map(struct intel_fbdev *fbdev, struct iosys_map *map) | ||
40 | +{ | 95 | +{ |
41 | + return NULL; | ||
42 | +} | 96 | +} |
43 | #endif | 97 | #endif |
44 | 98 | ||
45 | #endif /* __INTEL_FBDEV_H__ */ | 99 | #endif /* __INTEL_FBDEV_H__ */ |
100 | diff --git a/drivers/gpu/drm/i915/i915_vma.h b/drivers/gpu/drm/i915/i915_vma.h | ||
101 | index XXXXXXX..XXXXXXX 100644 | ||
102 | --- a/drivers/gpu/drm/i915/i915_vma.h | ||
103 | +++ b/drivers/gpu/drm/i915/i915_vma.h | ||
104 | @@ -XXX,XX +XXX,XX @@ static inline bool i915_node_color_differs(const struct drm_mm_node *node, | ||
105 | return drm_mm_node_allocated(node) && node->color != color; | ||
106 | } | ||
107 | |||
108 | +static inline void __iomem *i915_vma_get_iomap(struct i915_vma *vma) | ||
109 | +{ | ||
110 | + return READ_ONCE(vma->iomap); | ||
111 | +} | ||
112 | + | ||
113 | /** | ||
114 | * i915_vma_pin_iomap - calls ioremap_wc to map the GGTT VMA via the aperture | ||
115 | * @vma: VMA to iomap | ||
116 | diff --git a/drivers/gpu/drm/xe/display/xe_fb_pin.c b/drivers/gpu/drm/xe/display/xe_fb_pin.c | ||
117 | index XXXXXXX..XXXXXXX 100644 | ||
118 | --- a/drivers/gpu/drm/xe/display/xe_fb_pin.c | ||
119 | +++ b/drivers/gpu/drm/xe/display/xe_fb_pin.c | ||
120 | @@ -XXX,XX +XXX,XX @@ u64 intel_dpt_offset(struct i915_vma *dpt_vma) | ||
121 | { | ||
122 | return 0; | ||
123 | } | ||
124 | + | ||
125 | +void intel_fb_get_map(struct i915_vma *vma, struct iosys_map *map) | ||
126 | +{ | ||
127 | + *map = vma->bo->vmap; | ||
128 | +} | ||
46 | -- | 129 | -- |
47 | 2.47.0 | 130 | 2.49.0 | diff view generated by jsdifflib |
1 | drm_panic draws in linear framebuffer, so it's easier to re-use the | 1 | drm_panic draws in linear framebuffer, so it's easier to re-use the |
---|---|---|---|
2 | current framebuffer, and disable tiling in the panic handler, to show | 2 | current framebuffer, and disable tiling in the panic handler, to show |
3 | the panic screen. | 3 | the panic screen. |
4 | 4 | ||
5 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> | 5 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> |
6 | --- | 6 | --- |
7 | drivers/gpu/drm/i915/display/i9xx_plane.c | 24 +++++++++++++++++++ | 7 | drivers/gpu/drm/i915/display/i9xx_plane.c | 23 +++++++++++++++++++ |
8 | .../drm/i915/display/intel_display_types.h | 2 ++ | 8 | .../drm/i915/display/intel_display_types.h | 2 ++ |
9 | 2 files changed, 26 insertions(+) | 9 | 2 files changed, 25 insertions(+) |
10 | 10 | ||
11 | diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c | 11 | diff --git a/drivers/gpu/drm/i915/display/i9xx_plane.c b/drivers/gpu/drm/i915/display/i9xx_plane.c |
12 | index XXXXXXX..XXXXXXX 100644 | 12 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/drivers/gpu/drm/i915/display/i9xx_plane.c | 13 | --- a/drivers/gpu/drm/i915/display/i9xx_plane.c |
14 | +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c | 14 | +++ b/drivers/gpu/drm/i915/display/i9xx_plane.c |
15 | @@ -XXX,XX +XXX,XX @@ static const struct drm_plane_funcs i8xx_plane_funcs = { | 15 | @@ -XXX,XX +XXX,XX @@ static const struct drm_plane_funcs i8xx_plane_funcs = { |
16 | .format_mod_supported = i8xx_plane_format_mod_supported, | 16 | .format_mod_supported = i8xx_plane_format_mod_supported, |
17 | }; | 17 | }; |
18 | 18 | ||
19 | +static void i9xx_disable_tiling(struct intel_plane *plane) | 19 | +static void i9xx_disable_tiling(struct intel_plane *plane) |
20 | +{ | 20 | +{ |
21 | + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); | 21 | + struct intel_display *display = to_intel_display(plane); |
22 | + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; | 22 | + enum i9xx_plane_id i9xx_plane = plane->i9xx_plane; |
23 | + struct intel_plane_state *plane_state = to_intel_plane_state(plane->base.state); | ||
24 | + u32 dspcntr; | 23 | + u32 dspcntr; |
24 | + u32 reg; | ||
25 | + | 25 | + |
26 | + dspcntr = intel_de_read_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane)); | 26 | + dspcntr = intel_de_read_fw(display, DSPCNTR(display, i9xx_plane)); |
27 | + dspcntr &= ~DISP_TILED; | 27 | + dspcntr &= ~DISP_TILED; |
28 | + intel_de_write_fw(dev_priv, DSPCNTR(dev_priv, i9xx_plane), dspcntr); | 28 | + intel_de_write_fw(display, DSPCNTR(display, i9xx_plane), dspcntr); |
29 | + | 29 | + |
30 | + if (DISPLAY_VER(dev_priv) >= 4) { | 30 | + if (DISPLAY_VER(display) >= 4) { |
31 | + u32 reg; | 31 | + reg = intel_de_read_fw(display, DSPSURF(display, i9xx_plane)); |
32 | + intel_de_write_fw(display, DSPSURF(display, i9xx_plane), reg); | ||
32 | + | 33 | + |
33 | + reg = intel_de_read_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane)); | 34 | + } else { |
34 | + intel_de_write_fw(dev_priv, DSPSURF(dev_priv, i9xx_plane), reg); | 35 | + reg = intel_de_read_fw(display, DSPADDR(display, i9xx_plane)); |
35 | + | 36 | + intel_de_write_fw(display, DSPADDR(display, i9xx_plane), reg); |
36 | + } else | 37 | + } |
37 | + intel_de_write_fw(dev_priv, DSPADDR(dev_priv, i9xx_plane), | ||
38 | + intel_plane_ggtt_offset(plane_state)); | ||
39 | +} | 38 | +} |
40 | + | 39 | + |
41 | struct intel_plane * | 40 | struct intel_plane * |
42 | intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) | 41 | intel_primary_plane_create(struct intel_display *display, enum pipe pipe) |
43 | { | 42 | { |
44 | @@ -XXX,XX +XXX,XX @@ intel_primary_plane_create(struct drm_i915_private *dev_priv, enum pipe pipe) | 43 | @@ -XXX,XX +XXX,XX @@ intel_primary_plane_create(struct intel_display *display, enum pipe pipe) |
45 | plane->disable_flip_done = ilk_primary_disable_flip_done; | 44 | } |
46 | } | 45 | } |
47 | 46 | ||
48 | + plane->disable_tiling = i9xx_disable_tiling; | 47 | + plane->disable_tiling = i9xx_disable_tiling; |
49 | + | 48 | + |
50 | modifiers = intel_fb_plane_get_modifiers(dev_priv, INTEL_PLANE_CAP_TILING_X); | 49 | modifiers = intel_fb_plane_get_modifiers(display, INTEL_PLANE_CAP_TILING_X); |
51 | 50 | ||
52 | if (DISPLAY_VER(dev_priv) >= 5 || IS_G4X(dev_priv)) | 51 | if (DISPLAY_VER(display) >= 5 || display->platform.g4x) |
53 | diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h | 52 | diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h |
54 | index XXXXXXX..XXXXXXX 100644 | 53 | index XXXXXXX..XXXXXXX 100644 |
55 | --- a/drivers/gpu/drm/i915/display/intel_display_types.h | 54 | --- a/drivers/gpu/drm/i915/display/intel_display_types.h |
56 | +++ b/drivers/gpu/drm/i915/display/intel_display_types.h | 55 | +++ b/drivers/gpu/drm/i915/display/intel_display_types.h |
57 | @@ -XXX,XX +XXX,XX @@ struct intel_plane { | 56 | @@ -XXX,XX +XXX,XX @@ struct intel_plane { |
... | ... | ||
62 | + void (*disable_tiling)(struct intel_plane *plane); | 61 | + void (*disable_tiling)(struct intel_plane *plane); |
63 | }; | 62 | }; |
64 | 63 | ||
65 | #define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base) | 64 | #define to_intel_atomic_state(x) container_of(x, struct intel_atomic_state, base) |
66 | -- | 65 | -- |
67 | 2.47.0 | 66 | 2.49.0 | diff view generated by jsdifflib |
... | ... | ||
---|---|---|---|
9 | 9 | ||
10 | diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c | 10 | diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c |
11 | index XXXXXXX..XXXXXXX 100644 | 11 | index XXXXXXX..XXXXXXX 100644 |
12 | --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c | 12 | --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c |
13 | +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c | 13 | +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c |
14 | @@ -XXX,XX +XXX,XX @@ static u8 skl_get_plane_caps(struct drm_i915_private *i915, | 14 | @@ -XXX,XX +XXX,XX @@ static u8 tgl_plane_caps(struct intel_display *display, |
15 | return caps; | 15 | return caps; |
16 | } | 16 | } |
17 | 17 | ||
18 | +static void skl_disable_tiling(struct intel_plane *plane) | 18 | +static void skl_disable_tiling(struct intel_plane *plane) |
19 | +{ | 19 | +{ |
20 | + struct intel_plane_state *state = to_intel_plane_state(plane->base.state); | ||
21 | + struct intel_display *display = to_intel_display(plane); | ||
22 | + u32 stride = state->view.color_plane[0].scanout_stride / 64; | ||
20 | + u32 plane_ctl; | 23 | + u32 plane_ctl; |
21 | + struct intel_plane_state *state = to_intel_plane_state(plane->base.state); | ||
22 | + struct drm_i915_private *dev_priv = to_i915(plane->base.dev); | ||
23 | + u32 stride = state->view.color_plane[0].scanout_stride / 64; | ||
24 | + | 24 | + |
25 | + plane_ctl = intel_de_read(dev_priv, PLANE_CTL(plane->pipe, plane->id)); | 25 | + plane_ctl = intel_de_read(display, PLANE_CTL(plane->pipe, plane->id)); |
26 | + plane_ctl &= ~PLANE_CTL_TILED_MASK; | 26 | + plane_ctl &= ~PLANE_CTL_TILED_MASK; |
27 | + | 27 | + |
28 | + intel_de_write_fw(dev_priv, PLANE_STRIDE(plane->pipe, plane->id), | 28 | + intel_de_write_fw(display, PLANE_STRIDE(plane->pipe, plane->id), |
29 | + PLANE_STRIDE_(stride)); | 29 | + PLANE_STRIDE_(stride)); |
30 | + | 30 | + |
31 | + intel_de_write_fw(dev_priv, PLANE_CTL(plane->pipe, plane->id), plane_ctl); | 31 | + intel_de_write_fw(display, PLANE_CTL(plane->pipe, plane->id), plane_ctl); |
32 | + | 32 | + |
33 | + intel_de_write_fw(dev_priv, PLANE_SURF(plane->pipe, plane->id), | 33 | + intel_de_write_fw(display, PLANE_SURF(plane->pipe, plane->id), |
34 | + skl_plane_surf(state, 0)); | 34 | + skl_plane_surf(state, 0)); |
35 | +} | 35 | +} |
36 | + | 36 | + |
37 | struct intel_plane * | 37 | struct intel_plane * |
38 | skl_universal_plane_create(struct drm_i915_private *dev_priv, | 38 | skl_universal_plane_create(struct intel_display *display, |
39 | enum pipe pipe, enum plane_id plane_id) | 39 | enum pipe pipe, enum plane_id plane_id) |
40 | @@ -XXX,XX +XXX,XX @@ skl_universal_plane_create(struct drm_i915_private *dev_priv, | 40 | @@ -XXX,XX +XXX,XX @@ skl_universal_plane_create(struct intel_display *display, |
41 | plane->max_height = skl_plane_max_height; | 41 | plane->max_height = skl_plane_max_height; |
42 | plane->min_cdclk = skl_plane_min_cdclk; | 42 | plane->min_cdclk = skl_plane_min_cdclk; |
43 | } | 43 | } |
44 | + plane->disable_tiling = skl_disable_tiling; | 44 | + plane->disable_tiling = skl_disable_tiling; |
45 | 45 | ||
46 | if (DISPLAY_VER(dev_priv) >= 13) | 46 | if (DISPLAY_VER(display) >= 13) |
47 | plane->max_stride = adl_plane_max_stride; | 47 | plane->max_stride = adl_plane_max_stride; |
48 | -- | 48 | -- |
49 | 2.47.0 | 49 | 2.49.0 | diff view generated by jsdifflib |
1 | Prepare the work for drm_panic support. They are used to map the | 1 | Prepare the work for drm_panic support. This is used to map the |
---|---|---|---|
2 | current framebuffer, so the CPU can access it, and draws the panic | 2 | current framebuffer, so the CPU can overwrite it with the panic |
3 | screen. | 3 | message. |
4 | 4 | ||
5 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> | 5 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> |
6 | --- | 6 | --- |
7 | drivers/gpu/drm/i915/gem/i915_gem_object.h | 5 +++++ | ||
8 | drivers/gpu/drm/i915/gem/i915_gem_pages.c | 4 ++-- | ||
9 | 2 files changed, 7 insertions(+), 2 deletions(-) | ||
10 | 7 | ||
8 | v5: | ||
9 | * Use iosys_map for intel_bo_panic_map(). | ||
10 | |||
11 | drivers/gpu/drm/i915/display/intel_bo.c | 5 ++++ | ||
12 | drivers/gpu/drm/i915/display/intel_bo.h | 1 + | ||
13 | drivers/gpu/drm/i915/gem/i915_gem_object.h | 2 ++ | ||
14 | drivers/gpu/drm/i915/gem/i915_gem_pages.c | 29 ++++++++++++++++++++++ | ||
15 | drivers/gpu/drm/xe/display/intel_bo.c | 10 ++++++++ | ||
16 | 5 files changed, 47 insertions(+) | ||
17 | |||
18 | diff --git a/drivers/gpu/drm/i915/display/intel_bo.c b/drivers/gpu/drm/i915/display/intel_bo.c | ||
19 | index XXXXXXX..XXXXXXX 100644 | ||
20 | --- a/drivers/gpu/drm/i915/display/intel_bo.c | ||
21 | +++ b/drivers/gpu/drm/i915/display/intel_bo.c | ||
22 | @@ -XXX,XX +XXX,XX @@ void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) | ||
23 | { | ||
24 | i915_debugfs_describe_obj(m, to_intel_bo(obj)); | ||
25 | } | ||
26 | + | ||
27 | +void intel_bo_panic_map(struct drm_gem_object *obj, struct iosys_map *map) | ||
28 | +{ | ||
29 | + i915_gem_object_panic_map(to_intel_bo(obj), map); | ||
30 | +} | ||
31 | diff --git a/drivers/gpu/drm/i915/display/intel_bo.h b/drivers/gpu/drm/i915/display/intel_bo.h | ||
32 | index XXXXXXX..XXXXXXX 100644 | ||
33 | --- a/drivers/gpu/drm/i915/display/intel_bo.h | ||
34 | +++ b/drivers/gpu/drm/i915/display/intel_bo.h | ||
35 | @@ -XXX,XX +XXX,XX @@ struct intel_frontbuffer *intel_bo_set_frontbuffer(struct drm_gem_object *obj, | ||
36 | struct intel_frontbuffer *front); | ||
37 | |||
38 | void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj); | ||
39 | +void intel_bo_panic_map(struct drm_gem_object *obj, struct iosys_map *map); | ||
40 | |||
41 | #endif /* __INTEL_BO__ */ | ||
11 | diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h | 42 | diff --git a/drivers/gpu/drm/i915/gem/i915_gem_object.h b/drivers/gpu/drm/i915/gem/i915_gem_object.h |
12 | index XXXXXXX..XXXXXXX 100644 | 43 | index XXXXXXX..XXXXXXX 100644 |
13 | --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h | 44 | --- a/drivers/gpu/drm/i915/gem/i915_gem_object.h |
14 | +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h | 45 | +++ b/drivers/gpu/drm/i915/gem/i915_gem_object.h |
15 | @@ -XXX,XX +XXX,XX @@ i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj) | 46 | @@ -XXX,XX +XXX,XX @@ i915_gem_object_unpin_pages(struct drm_i915_gem_object *obj) |
16 | int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj); | 47 | int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj); |
17 | int i915_gem_object_truncate(struct drm_i915_gem_object *obj); | 48 | int i915_gem_object_truncate(struct drm_i915_gem_object *obj); |
18 | 49 | ||
19 | +void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, | 50 | +void i915_gem_object_panic_map(struct drm_i915_gem_object *obj, struct iosys_map *map); |
20 | + enum i915_map_type type); | ||
21 | +void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj, | ||
22 | + enum i915_map_type type); | ||
23 | + | 51 | + |
24 | /** | 52 | /** |
25 | * i915_gem_object_pin_map - return a contiguous mapping of the entire object | 53 | * i915_gem_object_pin_map - return a contiguous mapping of the entire object |
26 | * @obj: the object to map into kernel address space | 54 | * @obj: the object to map into kernel address space |
27 | diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c | 55 | diff --git a/drivers/gpu/drm/i915/gem/i915_gem_pages.c b/drivers/gpu/drm/i915/gem/i915_gem_pages.c |
28 | index XXXXXXX..XXXXXXX 100644 | 56 | index XXXXXXX..XXXXXXX 100644 |
29 | --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c | 57 | --- a/drivers/gpu/drm/i915/gem/i915_gem_pages.c |
30 | +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c | 58 | +++ b/drivers/gpu/drm/i915/gem/i915_gem_pages.c |
31 | @@ -XXX,XX +XXX,XX @@ int __i915_gem_object_put_pages(struct drm_i915_gem_object *obj) | 59 | @@ -XXX,XX +XXX,XX @@ static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj, |
32 | } | ||
33 | |||
34 | /* The 'mapping' part of i915_gem_object_pin_map() below */ | ||
35 | -static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, | ||
36 | +void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, | ||
37 | enum i915_map_type type) | ||
38 | { | ||
39 | unsigned long n_pages = obj->base.size >> PAGE_SHIFT, i; | ||
40 | @@ -XXX,XX +XXX,XX @@ static void *i915_gem_object_map_page(struct drm_i915_gem_object *obj, | ||
41 | return vaddr ?: ERR_PTR(-ENOMEM); | 60 | return vaddr ?: ERR_PTR(-ENOMEM); |
42 | } | 61 | } |
43 | 62 | ||
44 | -static void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj, | 63 | +/* Map the current framebuffer for CPU access. Called from panic handler, so no |
45 | +void *i915_gem_object_map_pfn(struct drm_i915_gem_object *obj, | 64 | + * need to pin or cleanup. |
46 | enum i915_map_type type) | 65 | + */ |
66 | +void i915_gem_object_panic_map(struct drm_i915_gem_object *obj, struct iosys_map *map) | ||
67 | +{ | ||
68 | + enum i915_map_type has_type; | ||
69 | + void *ptr; | ||
70 | + | ||
71 | + ptr = page_unpack_bits(obj->mm.mapping, &has_type); | ||
72 | + | ||
73 | + | ||
74 | + if (!ptr) { | ||
75 | + if (i915_gem_object_has_struct_page(obj)) | ||
76 | + ptr = i915_gem_object_map_page(obj, I915_MAP_WB); | ||
77 | + else | ||
78 | + ptr = i915_gem_object_map_pfn(obj, I915_MAP_WB); | ||
79 | + | ||
80 | + if (IS_ERR(ptr)) | ||
81 | + return; | ||
82 | + | ||
83 | + obj->mm.mapping = page_pack_bits(ptr, I915_MAP_WB); | ||
84 | + } | ||
85 | + | ||
86 | + if (i915_gem_object_has_iomem(obj)) | ||
87 | + iosys_map_set_vaddr_iomem(map, (void __iomem *) ptr); | ||
88 | + else | ||
89 | + iosys_map_set_vaddr(map, ptr); | ||
90 | +} | ||
91 | + | ||
92 | /* get, pin, and map the pages of the object into kernel space */ | ||
93 | void *i915_gem_object_pin_map(struct drm_i915_gem_object *obj, | ||
94 | enum i915_map_type type) | ||
95 | diff --git a/drivers/gpu/drm/xe/display/intel_bo.c b/drivers/gpu/drm/xe/display/intel_bo.c | ||
96 | index XXXXXXX..XXXXXXX 100644 | ||
97 | --- a/drivers/gpu/drm/xe/display/intel_bo.c | ||
98 | +++ b/drivers/gpu/drm/xe/display/intel_bo.c | ||
99 | @@ -XXX,XX +XXX,XX @@ void intel_bo_describe(struct seq_file *m, struct drm_gem_object *obj) | ||
47 | { | 100 | { |
48 | resource_size_t iomap = obj->mm.region->iomap.base - | 101 | /* FIXME */ |
102 | } | ||
103 | + | ||
104 | +void intel_bo_panic_map(struct drm_gem_object *obj, struct iosys_map *map) | ||
105 | +{ | ||
106 | + struct xe_bo *bo = gem_to_xe_bo(obj); | ||
107 | + int ret; | ||
108 | + | ||
109 | + ret = ttm_bo_vmap(&bo->ttm, map); | ||
110 | + if (ret) | ||
111 | + iosys_map_clear(map); | ||
112 | +} | ||
49 | -- | 113 | -- |
50 | 2.47.0 | 114 | 2.49.0 | diff view generated by jsdifflib |
1 | This adds drm_panic support for a wide range of Intel GPU. I've | 1 | This adds drm_panic support for a wide range of Intel GPU. I've |
---|---|---|---|
2 | tested it only on 3 laptops, haswell (with 128MB of eDRAM), | 2 | tested it only on 4 laptops, Haswell (with 128MB of eDRAM), |
3 | cometlake and alderlake. | 3 | Comet Lake, Raptor Lake, and Lunar Lake. |
4 | 4 | For hardware using DPT, it's not possible to disable tiling, as you | |
5 | * DPT: if I disable tiling on a framebuffer using DPT, then it | 5 | will need to reconfigure the way the GPU is accessing the |
6 | displays some other memory location. As DPT is enabled only for | 6 | framebuffer. |
7 | tiled framebuffer, there might be some hardware limitations. | ||
8 | * fbdev: On my haswell laptop, the fbdev framebuffer is configured | ||
9 | with tiling enabled, but really it's linear, because fbcon don't | ||
10 | know about tiling, and the panic screen is perfect when it's drawn | ||
11 | as linear. | ||
12 | 7 | ||
13 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> | 8 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> |
14 | --- | 9 | --- |
15 | .../gpu/drm/i915/display/intel_atomic_plane.c | 98 ++++++++++++++++++- | 10 | |
16 | 1 file changed, 97 insertions(+), 1 deletion(-) | 11 | v4: |
12 | * Add support for Xe driver. | ||
13 | |||
14 | v6: | ||
15 | * Use struct intel_display instead of drm_i915_private for intel_atomic_plane.c | ||
16 | |||
17 | .../gpu/drm/i915/display/intel_atomic_plane.c | 79 ++++++++++++++++++- | ||
18 | 1 file changed, 78 insertions(+), 1 deletion(-) | ||
17 | 19 | ||
18 | diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c | 20 | diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c |
19 | index XXXXXXX..XXXXXXX 100644 | 21 | index XXXXXXX..XXXXXXX 100644 |
20 | --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c | 22 | --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c |
21 | +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c | 23 | +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c |
... | ... | ||
25 | #include <linux/dma-resv.h> | 27 | #include <linux/dma-resv.h> |
26 | +#include <linux/iosys-map.h> | 28 | +#include <linux/iosys-map.h> |
27 | 29 | ||
28 | #include <drm/drm_atomic_helper.h> | 30 | #include <drm/drm_atomic_helper.h> |
29 | #include <drm/drm_blend.h> | 31 | #include <drm/drm_blend.h> |
32 | #include <drm/drm_damage_helper.h> | ||
30 | +#include <drm/drm_cache.h> | 33 | +#include <drm/drm_cache.h> |
31 | #include <drm/drm_fourcc.h> | 34 | #include <drm/drm_fourcc.h> |
32 | #include <drm/drm_gem.h> | 35 | #include <drm/drm_gem.h> |
33 | #include <drm/drm_gem_atomic_helper.h> | 36 | #include <drm/drm_gem_atomic_helper.h> |
34 | +#include <drm/drm_panic.h> | 37 | +#include <drm/drm_panic.h> |
35 | 38 | ||
36 | +#include "gem/i915_gem_object.h" | 39 | #include "gem/i915_gem_object.h" |
37 | #include "i915_config.h" | 40 | #include "i915_config.h" |
41 | @@ -XXX,XX +XXX,XX @@ | ||
42 | #include "i915_vma.h" | ||
38 | #include "i9xx_plane_regs.h" | 43 | #include "i9xx_plane_regs.h" |
39 | #include "intel_atomic_plane.h" | 44 | #include "intel_atomic_plane.h" |
45 | +#include "intel_bo.h" | ||
46 | #include "intel_cdclk.h" | ||
47 | #include "intel_cursor.h" | ||
48 | #include "intel_display_rps.h" | ||
40 | @@ -XXX,XX +XXX,XX @@ | 49 | @@ -XXX,XX +XXX,XX @@ |
41 | #include "intel_display_types.h" | 50 | #include "intel_display_types.h" |
42 | #include "intel_fb.h" | 51 | #include "intel_fb.h" |
43 | #include "intel_fb_pin.h" | 52 | #include "intel_fb_pin.h" |
44 | +#include "intel_fbdev.h" | 53 | +#include "intel_fbdev.h" |
45 | #include "skl_scaler.h" | 54 | #include "skl_scaler.h" |
55 | #include "skl_universal_plane.h" | ||
46 | #include "skl_watermark.h" | 56 | #include "skl_watermark.h" |
47 | |||
48 | @@ -XXX,XX +XXX,XX @@ intel_cleanup_plane_fb(struct drm_plane *plane, | 57 | @@ -XXX,XX +XXX,XX @@ intel_cleanup_plane_fb(struct drm_plane *plane, |
49 | intel_plane_unpin_fb(old_plane_state); | 58 | intel_plane_unpin_fb(old_plane_state); |
50 | } | 59 | } |
51 | 60 | ||
52 | +/* Only used by drm_panic get_scanout_buffer() and panic_flush(), so it is | 61 | +/* Only used by drm_panic get_scanout_buffer() and panic_flush(), so it is |
... | ... | ||
55 | +static struct iosys_map panic_map; | 64 | +static struct iosys_map panic_map; |
56 | + | 65 | + |
57 | +static void intel_panic_flush(struct drm_plane *plane) | 66 | +static void intel_panic_flush(struct drm_plane *plane) |
58 | +{ | 67 | +{ |
59 | + struct intel_plane_state *plane_state = to_intel_plane_state(plane->state); | 68 | + struct intel_plane_state *plane_state = to_intel_plane_state(plane->state); |
60 | + struct drm_i915_private *dev_priv = to_i915(plane->dev); | 69 | + struct intel_plane *iplane = to_intel_plane(plane); |
70 | + struct intel_display *display = to_intel_display(iplane); | ||
61 | + struct drm_framebuffer *fb = plane_state->hw.fb; | 71 | + struct drm_framebuffer *fb = plane_state->hw.fb; |
62 | + struct intel_plane *iplane = to_intel_plane(plane); | ||
63 | + | 72 | + |
64 | + /* Force a cache flush, otherwise the new pixels won't show up */ | 73 | + /* Force a cache flush, otherwise the new pixels won't show up */ |
65 | + drm_clflush_virt_range(panic_map.vaddr, fb->height * fb->pitches[0]); | 74 | + drm_clflush_virt_range(panic_map.vaddr, fb->height * fb->pitches[0]); |
66 | + | 75 | + |
67 | + /* Don't disable tiling if it's the fbdev framebuffer.*/ | 76 | + /* Don't disable tiling if it's the fbdev framebuffer.*/ |
68 | + if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev)) | 77 | + if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(display->fbdev.fbdev)) { |
69 | + return; | 78 | + return; |
70 | + | 79 | + |
71 | + if (fb->modifier && iplane->disable_tiling) | 80 | + if (fb->modifier && iplane->disable_tiling) |
72 | + iplane->disable_tiling(iplane); | 81 | + iplane->disable_tiling(iplane); |
73 | +} | 82 | +} |
74 | + | 83 | + |
75 | +static int intel_get_scanout_buffer(struct drm_plane *plane, | 84 | +static int intel_get_scanout_buffer(struct drm_plane *plane, |
76 | + struct drm_scanout_buffer *sb) | 85 | + struct drm_scanout_buffer *sb) |
77 | +{ | 86 | +{ |
78 | + struct intel_plane_state *plane_state; | 87 | + struct intel_plane_state *plane_state; |
79 | + struct drm_gem_object *gem_obj; | 88 | + struct drm_gem_object *obj; |
80 | + struct drm_i915_gem_object *obj; | ||
81 | + struct drm_framebuffer *fb; | 89 | + struct drm_framebuffer *fb; |
82 | + struct drm_i915_private *dev_priv = to_i915(plane->dev); | 90 | + struct intel_display *display = to_intel_display(plane->dev); |
83 | + void *ptr; | ||
84 | + enum i915_map_type has_type; | ||
85 | + | 91 | + |
86 | + if (!plane->state || !plane->state->fb || !plane->state->visible) | 92 | + if (!plane->state || !plane->state->fb || !plane->state->visible) |
87 | + return -ENODEV; | 93 | + return -ENODEV; |
88 | + | 94 | + |
89 | + plane_state = to_intel_plane_state(plane->state); | 95 | + plane_state = to_intel_plane_state(plane->state); |
90 | + fb = plane_state->hw.fb; | 96 | + fb = plane_state->hw.fb; |
91 | + gem_obj = intel_fb_bo(fb); | 97 | + obj = intel_fb_bo(fb); |
92 | + if (!gem_obj) | 98 | + if (!obj) |
93 | + return -ENODEV; | 99 | + return -ENODEV; |
94 | + | 100 | + |
95 | + obj = to_intel_bo(gem_obj); | 101 | + iosys_map_clear(&panic_map); |
96 | + | 102 | + if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(display->fbdev.fbdev)) { |
97 | + if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(dev_priv->display.fbdev.fbdev)) { | 103 | + intel_fbdev_get_map(display->fbdev.fbdev, &panic_map); |
98 | + ptr = intel_fbdev_getvaddr(dev_priv->display.fbdev.fbdev); | ||
99 | + if (!ptr) | ||
100 | + return -ENOMEM; | ||
101 | + } else { | 104 | + } else { |
102 | + /* can't disable tiling if DPT is in use */ | 105 | + /* Can't disable tiling if DPT is in use */ |
103 | + if (fb->modifier && HAS_DPT(dev_priv)) | 106 | + if (intel_fb_uses_dpt(fb)) |
104 | + return -EOPNOTSUPP; | 107 | + return -EOPNOTSUPP; |
105 | + | 108 | + |
106 | + /* Taken from i915_gem_object_pin_map() */ | 109 | + intel_bo_panic_map(obj, &panic_map); |
107 | + ptr = page_unpack_bits(obj->mm.mapping, &has_type); | ||
108 | + if (!ptr) { | ||
109 | + if (i915_gem_object_has_struct_page(obj)) | ||
110 | + ptr = i915_gem_object_map_page(obj, I915_MAP_WB); | ||
111 | + else | ||
112 | + ptr = i915_gem_object_map_pfn(obj, I915_MAP_WB); | ||
113 | + if (IS_ERR(ptr)) | ||
114 | + return -ENOMEM; | ||
115 | + } | ||
116 | + } | 110 | + } |
117 | + | 111 | + if (iosys_map_is_null(&panic_map)) |
118 | + if (i915_gem_object_has_iomem(obj)) | 112 | + return -ENOMEM; |
119 | + iosys_map_set_vaddr_iomem(&panic_map, ptr); | ||
120 | + else | ||
121 | + iosys_map_set_vaddr(&panic_map, ptr); | ||
122 | + | 113 | + |
123 | + sb->map[0] = panic_map; | 114 | + sb->map[0] = panic_map; |
124 | + sb->width = fb->width; | 115 | + sb->width = fb->width; |
125 | + sb->height = fb->height; | 116 | + sb->height = fb->height; |
126 | + sb->format = fb->format; | 117 | + sb->format = fb->format; |
... | ... | ||
132 | static const struct drm_plane_helper_funcs intel_plane_helper_funcs = { | 123 | static const struct drm_plane_helper_funcs intel_plane_helper_funcs = { |
133 | .prepare_fb = intel_prepare_plane_fb, | 124 | .prepare_fb = intel_prepare_plane_fb, |
134 | .cleanup_fb = intel_cleanup_plane_fb, | 125 | .cleanup_fb = intel_cleanup_plane_fb, |
135 | }; | 126 | }; |
136 | 127 | ||
137 | + | ||
138 | +static const struct drm_plane_helper_funcs intel_primary_plane_helper_funcs = { | 128 | +static const struct drm_plane_helper_funcs intel_primary_plane_helper_funcs = { |
139 | + .prepare_fb = intel_prepare_plane_fb, | 129 | + .prepare_fb = intel_prepare_plane_fb, |
140 | + .cleanup_fb = intel_cleanup_plane_fb, | 130 | + .cleanup_fb = intel_cleanup_plane_fb, |
141 | + .get_scanout_buffer = intel_get_scanout_buffer, | 131 | + .get_scanout_buffer = intel_get_scanout_buffer, |
142 | + .panic_flush = intel_panic_flush, | 132 | + .panic_flush = intel_panic_flush, |
... | ... | ||
151 | + drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); | 141 | + drm_plane_helper_add(&plane->base, &intel_plane_helper_funcs); |
152 | } | 142 | } |
153 | 143 | ||
154 | void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, | 144 | void intel_plane_init_cursor_vblank_work(struct intel_plane_state *old_plane_state, |
155 | -- | 145 | -- |
156 | 2.47.0 | 146 | 2.49.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | On Lunar Lake, if the panic occurs when fbcon is active, the panic | ||
2 | screen is only partially visible on the screen. Adding this | ||
3 | intel_frontbuffer_flush() call solves the issue. | ||
4 | It's probably not safe to do that in the panic handler, but that's | ||
5 | still better than nothing. | ||
1 | 6 | ||
7 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> | ||
8 | --- | ||
9 | drivers/gpu/drm/i915/display/intel_atomic_plane.c | 7 +++++++ | ||
10 | 1 file changed, 7 insertions(+) | ||
11 | |||
12 | diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c | ||
15 | +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c | ||
16 | @@ -XXX,XX +XXX,XX @@ | ||
17 | #include "intel_fb.h" | ||
18 | #include "intel_fb_pin.h" | ||
19 | #include "intel_fbdev.h" | ||
20 | +#include "intel_frontbuffer.h" | ||
21 | #include "skl_scaler.h" | ||
22 | #include "skl_universal_plane.h" | ||
23 | #include "skl_watermark.h" | ||
24 | @@ -XXX,XX +XXX,XX @@ static void intel_panic_flush(struct drm_plane *plane) | ||
25 | |||
26 | /* Don't disable tiling if it's the fbdev framebuffer.*/ | ||
27 | if (to_intel_framebuffer(fb) == intel_fbdev_framebuffer(display->fbdev.fbdev)) { | ||
28 | + struct intel_frontbuffer *front = to_intel_frontbuffer(fb); | ||
29 | + struct drm_gem_object *obj = intel_fb_bo(fb); | ||
30 | + | ||
31 | + intel_bo_flush_if_display(obj); | ||
32 | + intel_frontbuffer_flush(front, ORIGIN_DIRTYFB); | ||
33 | return; | ||
34 | + } | ||
35 | |||
36 | if (fb->modifier && iplane->disable_tiling) | ||
37 | iplane->disable_tiling(iplane); | ||
38 | -- | ||
39 | 2.49.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | On Alder Lake and later, it's not possible to disable tiling when DPT | ||
2 | is enabled. | ||
3 | So this commit implements Y-Tiling support, to still be able to draw | ||
4 | the panic screen. | ||
1 | 5 | ||
6 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> | ||
7 | --- | ||
8 | .../gpu/drm/i915/display/intel_atomic_plane.c | 69 ++++++++++++++++++- | ||
9 | .../drm/i915/display/skl_universal_plane.c | 15 ++-- | ||
10 | 2 files changed, 77 insertions(+), 7 deletions(-) | ||
11 | |||
12 | diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c | ||
13 | index XXXXXXX..XXXXXXX 100644 | ||
14 | --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c | ||
15 | +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c | ||
16 | @@ -XXX,XX +XXX,XX @@ intel_cleanup_plane_fb(struct drm_plane *plane, | ||
17 | */ | ||
18 | static struct iosys_map panic_map; | ||
19 | |||
20 | +/* Handle Y-tiling, only if DPT is enabled (otherwise disabling tiling is easier) | ||
21 | + * All DPT hardware have 128-bytes width tiling, so Y-tile dimension is 32x32 | ||
22 | + * pixels for 32bits pixels. | ||
23 | + */ | ||
24 | +#define YTILE_WIDTH 32 | ||
25 | +#define YTILE_HEIGHT 32 | ||
26 | +#define YTILE_SIZE (YTILE_WIDTH * YTILE_HEIGHT * 4) | ||
27 | + | ||
28 | +static void intel_ytile_set_pixel(struct drm_scanout_buffer *sb, unsigned int x, unsigned int y, | ||
29 | + u32 color) | ||
30 | +{ | ||
31 | + u32 offset; | ||
32 | + unsigned int swizzle; | ||
33 | + unsigned int width_in_blocks = DIV_ROUND_UP(sb->width, 32); | ||
34 | + | ||
35 | + /* Block offset */ | ||
36 | + offset = ((y / YTILE_HEIGHT) * width_in_blocks + (x / YTILE_WIDTH)) * YTILE_SIZE; | ||
37 | + | ||
38 | + x = x % YTILE_WIDTH; | ||
39 | + y = y % YTILE_HEIGHT; | ||
40 | + | ||
41 | + /* bit order inside a block is x4 x3 x2 y4 y3 y2 y1 y0 x1 x0 */ | ||
42 | + swizzle = (x & 3) | ((y & 0x1f) << 2) | ((x & 0x1c) << 5); | ||
43 | + offset += swizzle * 4; | ||
44 | + iosys_map_wr(&sb->map[0], offset, u32, color); | ||
45 | +} | ||
46 | + | ||
47 | static void intel_panic_flush(struct drm_plane *plane) | ||
48 | { | ||
49 | struct intel_plane_state *plane_state = to_intel_plane_state(plane->state); | ||
50 | @@ -XXX,XX +XXX,XX @@ static void intel_panic_flush(struct drm_plane *plane) | ||
51 | iplane->disable_tiling(iplane); | ||
52 | } | ||
53 | |||
54 | +static void (*intel_get_tiling_func(u64 fb_modifier))(struct drm_scanout_buffer *sb, unsigned int x, | ||
55 | + unsigned int y, u32 color) | ||
56 | +{ | ||
57 | + switch (fb_modifier) { | ||
58 | + case I915_FORMAT_MOD_Y_TILED: | ||
59 | + case I915_FORMAT_MOD_Y_TILED_CCS: | ||
60 | + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS_CC: | ||
61 | + case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: | ||
62 | + case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: | ||
63 | + return intel_ytile_set_pixel; | ||
64 | + case I915_FORMAT_MOD_X_TILED: | ||
65 | + case I915_FORMAT_MOD_4_TILED: | ||
66 | + case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS: | ||
67 | + case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS: | ||
68 | + case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS_CC: | ||
69 | + case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS: | ||
70 | + case I915_FORMAT_MOD_4_TILED_MTL_RC_CCS_CC: | ||
71 | + case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS: | ||
72 | + case I915_FORMAT_MOD_4_TILED_BMG_CCS: | ||
73 | + case I915_FORMAT_MOD_4_TILED_LNL_CCS: | ||
74 | + case I915_FORMAT_MOD_Yf_TILED: | ||
75 | + case I915_FORMAT_MOD_Yf_TILED_CCS: | ||
76 | + default: | ||
77 | + /* Not supported yet */ | ||
78 | + return NULL; | ||
79 | + } | ||
80 | +} | ||
81 | + | ||
82 | static int intel_get_scanout_buffer(struct drm_plane *plane, | ||
83 | struct drm_scanout_buffer *sb) | ||
84 | { | ||
85 | @@ -XXX,XX +XXX,XX @@ static int intel_get_scanout_buffer(struct drm_plane *plane, | ||
86 | intel_fbdev_get_map(display->fbdev.fbdev, &panic_map); | ||
87 | } else { | ||
88 | /* Can't disable tiling if DPT is in use */ | ||
89 | - if (intel_fb_uses_dpt(fb)) | ||
90 | - return -EOPNOTSUPP; | ||
91 | + if (intel_fb_uses_dpt(fb)) { | ||
92 | + if (fb->format->cpp[0] != 4) | ||
93 | + return -EOPNOTSUPP; | ||
94 | + sb->set_pixel = intel_get_tiling_func(fb->modifier); | ||
95 | + if (!sb->set_pixel) | ||
96 | + return -EOPNOTSUPP; | ||
97 | + } | ||
98 | |||
99 | intel_bo_panic_map(obj, &panic_map); | ||
100 | } | ||
101 | @@ -XXX,XX +XXX,XX @@ static int intel_get_scanout_buffer(struct drm_plane *plane, | ||
102 | sb->map[0] = panic_map; | ||
103 | sb->width = fb->width; | ||
104 | sb->height = fb->height; | ||
105 | - sb->format = fb->format; | ||
106 | + /* Use the generic linear format, because tiling, RC, CCS, CC | ||
107 | + * will be disabled in disable_tiling() | ||
108 | + */ | ||
109 | + sb->format = drm_format_info(fb->format->format); | ||
110 | sb->pitch[0] = fb->pitches[0]; | ||
111 | |||
112 | return 0; | ||
113 | diff --git a/drivers/gpu/drm/i915/display/skl_universal_plane.c b/drivers/gpu/drm/i915/display/skl_universal_plane.c | ||
114 | index XXXXXXX..XXXXXXX 100644 | ||
115 | --- a/drivers/gpu/drm/i915/display/skl_universal_plane.c | ||
116 | +++ b/drivers/gpu/drm/i915/display/skl_universal_plane.c | ||
117 | @@ -XXX,XX +XXX,XX @@ static void skl_disable_tiling(struct intel_plane *plane) | ||
118 | { | ||
119 | struct intel_plane_state *state = to_intel_plane_state(plane->base.state); | ||
120 | struct intel_display *display = to_intel_display(plane); | ||
121 | - u32 stride = state->view.color_plane[0].scanout_stride / 64; | ||
122 | + const struct drm_framebuffer *fb = state->hw.fb; | ||
123 | u32 plane_ctl; | ||
124 | |||
125 | plane_ctl = intel_de_read(display, PLANE_CTL(plane->pipe, plane->id)); | ||
126 | - plane_ctl &= ~PLANE_CTL_TILED_MASK; | ||
127 | |||
128 | - intel_de_write_fw(display, PLANE_STRIDE(plane->pipe, plane->id), | ||
129 | - PLANE_STRIDE_(stride)); | ||
130 | + if (intel_fb_uses_dpt(fb)) { | ||
131 | + /* if DPT is enabled, keep tiling, but disable compression */ | ||
132 | + plane_ctl &= ~PLANE_CTL_RENDER_DECOMPRESSION_ENABLE; | ||
133 | + } else { | ||
134 | + /* if DPT is not supported, disable tiling, and update stride */ | ||
135 | + u32 stride = state->view.color_plane[0].scanout_stride / 64; | ||
136 | |||
137 | + plane_ctl &= ~PLANE_CTL_TILED_MASK; | ||
138 | + intel_de_write_fw(display, PLANE_STRIDE(plane->pipe, plane->id), | ||
139 | + PLANE_STRIDE_(stride)); | ||
140 | + } | ||
141 | intel_de_write_fw(display, PLANE_CTL(plane->pipe, plane->id), plane_ctl); | ||
142 | |||
143 | intel_de_write_fw(display, PLANE_SURF(plane->pipe, plane->id), | ||
144 | -- | ||
145 | 2.49.0 | diff view generated by jsdifflib |
New patch | |||
---|---|---|---|
1 | On Alder Lake and later, it's not possible to disable tiling when DPT | ||
2 | is enabled. | ||
3 | So this commit implements 4-Tiling support, to still be able to draw | ||
4 | the panic screen. | ||
1 | 5 | ||
6 | Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com> | ||
7 | --- | ||
8 | .../gpu/drm/i915/display/intel_atomic_plane.c | 22 ++++++++++++++++++- | ||
9 | 1 file changed, 21 insertions(+), 1 deletion(-) | ||
10 | |||
11 | diff --git a/drivers/gpu/drm/i915/display/intel_atomic_plane.c b/drivers/gpu/drm/i915/display/intel_atomic_plane.c | ||
12 | index XXXXXXX..XXXXXXX 100644 | ||
13 | --- a/drivers/gpu/drm/i915/display/intel_atomic_plane.c | ||
14 | +++ b/drivers/gpu/drm/i915/display/intel_atomic_plane.c | ||
15 | @@ -XXX,XX +XXX,XX @@ static void intel_ytile_set_pixel(struct drm_scanout_buffer *sb, unsigned int x, | ||
16 | iosys_map_wr(&sb->map[0], offset, u32, color); | ||
17 | } | ||
18 | |||
19 | +static void intel_4tile_set_pixel(struct drm_scanout_buffer *sb, unsigned int x, unsigned int y, | ||
20 | + u32 color) | ||
21 | +{ | ||
22 | + u32 offset; | ||
23 | + unsigned int swizzle; | ||
24 | + unsigned int width_in_blocks = DIV_ROUND_UP(sb->width, 32); | ||
25 | + | ||
26 | + /* Block offset */ | ||
27 | + offset = ((y / YTILE_HEIGHT) * width_in_blocks + (x / YTILE_WIDTH)) * YTILE_SIZE; | ||
28 | + | ||
29 | + x = x % YTILE_WIDTH; | ||
30 | + y = y % YTILE_HEIGHT; | ||
31 | + | ||
32 | + /* bit order inside a block is y4 y3 x4 y2 x3 x2 y1 y0 x1 x0 */ | ||
33 | + swizzle = (x & 3) | ((y & 3) << 2) | ((x & 0xc) << 2) | (y & 4) << 4 | ((x & 0x10) << 3) | ((y & 0x18) << 5); | ||
34 | + offset += swizzle * 4; | ||
35 | + iosys_map_wr(&sb->map[0], offset, u32, color); | ||
36 | +} | ||
37 | + | ||
38 | static void intel_panic_flush(struct drm_plane *plane) | ||
39 | { | ||
40 | struct intel_plane_state *plane_state = to_intel_plane_state(plane->state); | ||
41 | @@ -XXX,XX +XXX,XX @@ static void (*intel_get_tiling_func(u64 fb_modifier))(struct drm_scanout_buffer | ||
42 | case I915_FORMAT_MOD_Y_TILED_GEN12_RC_CCS: | ||
43 | case I915_FORMAT_MOD_Y_TILED_GEN12_MC_CCS: | ||
44 | return intel_ytile_set_pixel; | ||
45 | - case I915_FORMAT_MOD_X_TILED: | ||
46 | case I915_FORMAT_MOD_4_TILED: | ||
47 | case I915_FORMAT_MOD_4_TILED_DG2_RC_CCS: | ||
48 | case I915_FORMAT_MOD_4_TILED_DG2_MC_CCS: | ||
49 | @@ -XXX,XX +XXX,XX @@ static void (*intel_get_tiling_func(u64 fb_modifier))(struct drm_scanout_buffer | ||
50 | case I915_FORMAT_MOD_4_TILED_MTL_MC_CCS: | ||
51 | case I915_FORMAT_MOD_4_TILED_BMG_CCS: | ||
52 | case I915_FORMAT_MOD_4_TILED_LNL_CCS: | ||
53 | + return intel_4tile_set_pixel; | ||
54 | + case I915_FORMAT_MOD_X_TILED: | ||
55 | case I915_FORMAT_MOD_Yf_TILED: | ||
56 | case I915_FORMAT_MOD_Yf_TILED_CCS: | ||
57 | default: | ||
58 | -- | ||
59 | 2.49.0 | diff view generated by jsdifflib |