drivers/gpu/drm/hyperv/hyperv_drm_modeset.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/hyperv/hyperv_drm_modeset.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/hyperv/hyperv_drm_modeset.c
Extension
.c
Size
9552 bytes
Lines
341
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

// SPDX-License-Identifier: GPL-2.0-only
/*
 * Copyright 2021 Microsoft
 */

#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>
#include <drm/drm_format_helper.h>
#include <drm/drm_fourcc.h>
#include <drm/drm_framebuffer.h>
#include <drm/drm_gem_atomic_helper.h>
#include <drm/drm_gem_framebuffer_helper.h>
#include <drm/drm_gem_shmem_helper.h>
#include <drm/drm_probe_helper.h>
#include <drm/drm_panic.h>
#include <drm/drm_plane.h>
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>
#include <drm/drm_vblank_helper.h>

#include "hyperv_drm.h"

static int hyperv_blit_to_vram_rect(struct drm_framebuffer *fb,
				    const struct iosys_map *vmap,
				    struct drm_rect *rect)
{
	struct hyperv_drm_device *hv = to_hv(fb->dev);
	struct iosys_map dst = IOSYS_MAP_INIT_VADDR_IOMEM(hv->vram);
	int idx;

	if (!drm_dev_enter(&hv->dev, &idx))
		return -ENODEV;

	iosys_map_incr(&dst, drm_fb_clip_offset(fb->pitches[0], fb->format, rect));
	drm_fb_memcpy(&dst, fb->pitches, vmap, fb, rect);

	drm_dev_exit(idx);

	return 0;
}

static int hyperv_connector_get_modes(struct drm_connector *connector)
{
	struct hyperv_drm_device *hv = to_hv(connector->dev);
	int count;

	count = drm_add_modes_noedid(connector,
				     connector->dev->mode_config.max_width,
				     connector->dev->mode_config.max_height);
	drm_set_preferred_mode(connector, hv->preferred_width,
			       hv->preferred_height);

	return count;
}

static const struct drm_connector_helper_funcs hyperv_connector_helper_funcs = {
	.get_modes = hyperv_connector_get_modes,
};

static const struct drm_connector_funcs hyperv_connector_funcs = {
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = drm_connector_cleanup,
	.reset = drm_atomic_helper_connector_reset,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
};

static inline int hyperv_conn_init(struct hyperv_drm_device *hv)
{
	drm_connector_helper_add(&hv->connector, &hyperv_connector_helper_funcs);
	return drm_connector_init(&hv->dev, &hv->connector,
				  &hyperv_connector_funcs,
				  DRM_MODE_CONNECTOR_VIRTUAL);
}

static int hyperv_check_size(struct hyperv_drm_device *hv, int w, int h,
			     struct drm_framebuffer *fb)
{
	u32 pitch = w * (hv->screen_depth / 8);

	if (fb)
		pitch = fb->pitches[0];

	if (pitch * h > hv->fb_size)
		return -EINVAL;

Annotation

Implementation Notes