mirror of
https://github.com/torvalds/linux.git
synced 2026-05-31 02:24:24 +02:00
drm/hyperv: Replace simple-KMS with regular atomic helpers
Drop simple-KMS in favor of regular atomic helpers to make the code more modular. The simple-KMS helper mix up plane and CRTC state, so it is obsolete and should go away [1]. Since it just split the simple-pipe functions into per-plane and per-CRTC, no functional changes is expected. [1] https://lore.kernel.org/lkml/dae5089d-e214-4518-b927-5c4149babad8@suse.de/ Acked-by: Javier Martinez Canillas <javierm@redhat.com> Signed-off-by: Ryosuke Yasuoka <ryasuoka@redhat.com> Link: https://lore.kernel.org/r/20250427101825.812766-1-ryasuoka@redhat.com Signed-off-by: Jocelyn Falempe <jfalempe@redhat.com>
This commit is contained in:
parent
9934ab1805
commit
4963049ea1
|
|
@ -11,7 +11,9 @@
|
|||
struct hyperv_drm_device {
|
||||
/* drm */
|
||||
struct drm_device dev;
|
||||
struct drm_simple_display_pipe pipe;
|
||||
struct drm_plane plane;
|
||||
struct drm_crtc crtc;
|
||||
struct drm_encoder encoder;
|
||||
struct drm_connector connector;
|
||||
|
||||
/* mode */
|
||||
|
|
|
|||
|
|
@ -5,6 +5,8 @@
|
|||
|
||||
#include <linux/hyperv.h>
|
||||
|
||||
#include <drm/drm_atomic.h>
|
||||
#include <drm/drm_crtc_helper.h>
|
||||
#include <drm/drm_damage_helper.h>
|
||||
#include <drm/drm_drv.h>
|
||||
#include <drm/drm_edid.h>
|
||||
|
|
@ -15,7 +17,7 @@
|
|||
#include <drm/drm_gem_framebuffer_helper.h>
|
||||
#include <drm/drm_gem_shmem_helper.h>
|
||||
#include <drm/drm_probe_helper.h>
|
||||
#include <drm/drm_simple_kms_helper.h>
|
||||
#include <drm/drm_plane.h>
|
||||
|
||||
#include "hyperv_drm.h"
|
||||
|
||||
|
|
@ -38,18 +40,6 @@ static int hyperv_blit_to_vram_rect(struct drm_framebuffer *fb,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static int hyperv_blit_to_vram_fullscreen(struct drm_framebuffer *fb,
|
||||
const struct iosys_map *map)
|
||||
{
|
||||
struct drm_rect fullscreen = {
|
||||
.x1 = 0,
|
||||
.x2 = fb->width,
|
||||
.y1 = 0,
|
||||
.y2 = fb->height,
|
||||
};
|
||||
return hyperv_blit_to_vram_rect(fb, map, &fullscreen);
|
||||
}
|
||||
|
||||
static int hyperv_connector_get_modes(struct drm_connector *connector)
|
||||
{
|
||||
struct hyperv_drm_device *hv = to_hv(connector->dev);
|
||||
|
|
@ -98,30 +88,66 @@ static int hyperv_check_size(struct hyperv_drm_device *hv, int w, int h,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void hyperv_pipe_enable(struct drm_simple_display_pipe *pipe,
|
||||
struct drm_crtc_state *crtc_state,
|
||||
struct drm_plane_state *plane_state)
|
||||
static const uint32_t hyperv_formats[] = {
|
||||
DRM_FORMAT_XRGB8888,
|
||||
};
|
||||
|
||||
static const uint64_t hyperv_modifiers[] = {
|
||||
DRM_FORMAT_MOD_LINEAR,
|
||||
DRM_FORMAT_MOD_INVALID
|
||||
};
|
||||
|
||||
static void hyperv_crtc_helper_atomic_enable(struct drm_crtc *crtc,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct hyperv_drm_device *hv = to_hv(pipe->crtc.dev);
|
||||
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(plane_state);
|
||||
struct hyperv_drm_device *hv = to_hv(crtc->dev);
|
||||
struct drm_plane *plane = &hv->plane;
|
||||
struct drm_plane_state *plane_state = plane->state;
|
||||
struct drm_crtc_state *crtc_state = crtc->state;
|
||||
|
||||
hyperv_hide_hw_ptr(hv->hdev);
|
||||
hyperv_update_situation(hv->hdev, 1, hv->screen_depth,
|
||||
crtc_state->mode.hdisplay,
|
||||
crtc_state->mode.vdisplay,
|
||||
plane_state->fb->pitches[0]);
|
||||
hyperv_blit_to_vram_fullscreen(plane_state->fb, &shadow_plane_state->data[0]);
|
||||
}
|
||||
|
||||
static int hyperv_pipe_check(struct drm_simple_display_pipe *pipe,
|
||||
struct drm_plane_state *plane_state,
|
||||
struct drm_crtc_state *crtc_state)
|
||||
{
|
||||
struct hyperv_drm_device *hv = to_hv(pipe->crtc.dev);
|
||||
struct drm_framebuffer *fb = plane_state->fb;
|
||||
static const struct drm_crtc_helper_funcs hyperv_crtc_helper_funcs = {
|
||||
.atomic_check = drm_crtc_helper_atomic_check,
|
||||
.atomic_enable = hyperv_crtc_helper_atomic_enable,
|
||||
};
|
||||
|
||||
if (fb->format->format != DRM_FORMAT_XRGB8888)
|
||||
return -EINVAL;
|
||||
static const struct drm_crtc_funcs hyperv_crtc_funcs = {
|
||||
.reset = drm_atomic_helper_crtc_reset,
|
||||
.destroy = drm_crtc_cleanup,
|
||||
.set_config = drm_atomic_helper_set_config,
|
||||
.page_flip = drm_atomic_helper_page_flip,
|
||||
.atomic_duplicate_state = drm_atomic_helper_crtc_duplicate_state,
|
||||
.atomic_destroy_state = drm_atomic_helper_crtc_destroy_state,
|
||||
};
|
||||
|
||||
static int hyperv_plane_atomic_check(struct drm_plane *plane,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct drm_plane_state *plane_state = drm_atomic_get_new_plane_state(state, plane);
|
||||
struct hyperv_drm_device *hv = to_hv(plane->dev);
|
||||
struct drm_framebuffer *fb = plane_state->fb;
|
||||
struct drm_crtc *crtc = plane_state->crtc;
|
||||
struct drm_crtc_state *crtc_state = NULL;
|
||||
int ret;
|
||||
|
||||
if (crtc)
|
||||
crtc_state = drm_atomic_get_new_crtc_state(state, crtc);
|
||||
|
||||
ret = drm_atomic_helper_check_plane_state(plane_state, crtc_state,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
DRM_PLANE_NO_SCALING,
|
||||
false, false);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
if (!plane_state->visible)
|
||||
return 0;
|
||||
|
||||
if (fb->pitches[0] * fb->height > hv->fb_size) {
|
||||
drm_err(&hv->dev, "fb size requested by %s for %dX%d (pitch %d) greater than %ld\n",
|
||||
|
|
@ -132,53 +158,85 @@ static int hyperv_pipe_check(struct drm_simple_display_pipe *pipe,
|
|||
return 0;
|
||||
}
|
||||
|
||||
static void hyperv_pipe_update(struct drm_simple_display_pipe *pipe,
|
||||
struct drm_plane_state *old_state)
|
||||
static void hyperv_plane_atomic_update(struct drm_plane *plane,
|
||||
struct drm_atomic_state *state)
|
||||
{
|
||||
struct hyperv_drm_device *hv = to_hv(pipe->crtc.dev);
|
||||
struct drm_plane_state *state = pipe->plane.state;
|
||||
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(state);
|
||||
struct drm_rect rect;
|
||||
struct hyperv_drm_device *hv = to_hv(plane->dev);
|
||||
struct drm_plane_state *old_state = drm_atomic_get_old_plane_state(state, plane);
|
||||
struct drm_plane_state *new_state = drm_atomic_get_new_plane_state(state, plane);
|
||||
struct drm_shadow_plane_state *shadow_plane_state = to_drm_shadow_plane_state(new_state);
|
||||
struct drm_rect damage;
|
||||
struct drm_rect dst_clip;
|
||||
struct drm_atomic_helper_damage_iter iter;
|
||||
|
||||
if (drm_atomic_helper_damage_merged(old_state, state, &rect)) {
|
||||
hyperv_blit_to_vram_rect(state->fb, &shadow_plane_state->data[0], &rect);
|
||||
hyperv_update_dirt(hv->hdev, &rect);
|
||||
drm_atomic_helper_damage_iter_init(&iter, old_state, new_state);
|
||||
drm_atomic_for_each_plane_damage(&iter, &damage) {
|
||||
dst_clip = new_state->dst;
|
||||
|
||||
if (!drm_rect_intersect(&dst_clip, &damage))
|
||||
continue;
|
||||
|
||||
hyperv_blit_to_vram_rect(new_state->fb, &shadow_plane_state->data[0], &damage);
|
||||
hyperv_update_dirt(hv->hdev, &damage);
|
||||
}
|
||||
}
|
||||
|
||||
static const struct drm_simple_display_pipe_funcs hyperv_pipe_funcs = {
|
||||
.enable = hyperv_pipe_enable,
|
||||
.check = hyperv_pipe_check,
|
||||
.update = hyperv_pipe_update,
|
||||
DRM_GEM_SIMPLE_DISPLAY_PIPE_SHADOW_PLANE_FUNCS,
|
||||
static const struct drm_plane_helper_funcs hyperv_plane_helper_funcs = {
|
||||
DRM_GEM_SHADOW_PLANE_HELPER_FUNCS,
|
||||
.atomic_check = hyperv_plane_atomic_check,
|
||||
.atomic_update = hyperv_plane_atomic_update,
|
||||
};
|
||||
|
||||
static const uint32_t hyperv_formats[] = {
|
||||
DRM_FORMAT_XRGB8888,
|
||||
static const struct drm_plane_funcs hyperv_plane_funcs = {
|
||||
.update_plane = drm_atomic_helper_update_plane,
|
||||
.disable_plane = drm_atomic_helper_disable_plane,
|
||||
.destroy = drm_plane_cleanup,
|
||||
DRM_GEM_SHADOW_PLANE_FUNCS,
|
||||
};
|
||||
|
||||
static const uint64_t hyperv_modifiers[] = {
|
||||
DRM_FORMAT_MOD_LINEAR,
|
||||
DRM_FORMAT_MOD_INVALID
|
||||
static const struct drm_encoder_funcs hyperv_drm_simple_encoder_funcs_cleanup = {
|
||||
.destroy = drm_encoder_cleanup,
|
||||
};
|
||||
|
||||
static inline int hyperv_pipe_init(struct hyperv_drm_device *hv)
|
||||
{
|
||||
struct drm_device *dev = &hv->dev;
|
||||
struct drm_encoder *encoder = &hv->encoder;
|
||||
struct drm_plane *plane = &hv->plane;
|
||||
struct drm_crtc *crtc = &hv->crtc;
|
||||
struct drm_connector *connector = &hv->connector;
|
||||
int ret;
|
||||
|
||||
ret = drm_simple_display_pipe_init(&hv->dev,
|
||||
&hv->pipe,
|
||||
&hyperv_pipe_funcs,
|
||||
hyperv_formats,
|
||||
ARRAY_SIZE(hyperv_formats),
|
||||
hyperv_modifiers,
|
||||
&hv->connector);
|
||||
ret = drm_universal_plane_init(dev, plane, 0,
|
||||
&hyperv_plane_funcs,
|
||||
hyperv_formats, ARRAY_SIZE(hyperv_formats),
|
||||
hyperv_modifiers,
|
||||
DRM_PLANE_TYPE_PRIMARY, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
drm_plane_helper_add(plane, &hyperv_plane_helper_funcs);
|
||||
drm_plane_enable_fb_damage_clips(plane);
|
||||
|
||||
ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
|
||||
&hyperv_crtc_funcs, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
drm_crtc_helper_add(crtc, &hyperv_crtc_helper_funcs);
|
||||
|
||||
encoder->possible_crtcs = drm_crtc_mask(crtc);
|
||||
ret = drm_encoder_init(dev, encoder,
|
||||
&hyperv_drm_simple_encoder_funcs_cleanup,
|
||||
DRM_MODE_ENCODER_NONE, NULL);
|
||||
if (ret)
|
||||
return ret;
|
||||
|
||||
drm_plane_enable_fb_damage_clips(&hv->pipe.plane);
|
||||
ret = hyperv_conn_init(hv);
|
||||
if (ret) {
|
||||
drm_err(dev, "Failed to initialized connector.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
return 0;
|
||||
return drm_connector_attach_encoder(connector, encoder);
|
||||
}
|
||||
|
||||
static enum drm_mode_status
|
||||
|
|
@ -221,12 +279,6 @@ int hyperv_mode_config_init(struct hyperv_drm_device *hv)
|
|||
|
||||
dev->mode_config.funcs = &hyperv_mode_config_funcs;
|
||||
|
||||
ret = hyperv_conn_init(hv);
|
||||
if (ret) {
|
||||
drm_err(dev, "Failed to initialized connector.\n");
|
||||
return ret;
|
||||
}
|
||||
|
||||
ret = hyperv_pipe_init(hv);
|
||||
if (ret) {
|
||||
drm_err(dev, "Failed to initialized pipe.\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user