drivers/gpu/drm/xen/xen_drm_front_kms.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/xen/xen_drm_front_kms.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/xen/xen_drm_front_kms.c
Extension
.c
Size
10330 bytes
Lines
384
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

if (ret) {
			DRM_ERROR("Failed to send page flip request to backend: %d\n", ret);

			pipeline->conn_connected = false;
			/*
			 * Report the flip not handled, so pending event is
			 * sent, unblocking user-space.
			 */
			return false;
		}
		/*
		 * Signal that page flip was handled, pending event will be sent
		 * on frame done event from the backend.
		 */
		return true;
	}

	return false;
}

static int display_check(struct drm_simple_display_pipe *pipe,
			 struct drm_plane_state *plane_state,
			 struct drm_crtc_state *crtc_state)
{
	/*
	 * Xen doesn't initialize vblanking via drm_vblank_init(), so
	 * DRM helpers assume that it doesn't handle vblanking and start
	 * sending out fake VBLANK events automatically.
	 *
	 * As xen contains it's own logic for sending out VBLANK events
	 * in send_pending_event(), disable no_vblank (i.e., the xen
	 * driver has vblanking support).
	 */
	crtc_state->no_vblank = false;

	return 0;
}

static void display_update(struct drm_simple_display_pipe *pipe,
			   struct drm_plane_state *old_plane_state)
{
	struct xen_drm_front_drm_pipeline *pipeline =
			to_xen_drm_pipeline(pipe);
	struct drm_crtc *crtc = &pipe->crtc;
	struct drm_pending_vblank_event *event;
	int idx;

	event = crtc->state->event;
	if (event) {
		struct drm_device *dev = crtc->dev;
		unsigned long flags;

		WARN_ON(pipeline->pending_event);

		spin_lock_irqsave(&dev->event_lock, flags);
		crtc->state->event = NULL;

		pipeline->pending_event = event;
		spin_unlock_irqrestore(&dev->event_lock, flags);
	}

	if (!drm_dev_enter(pipe->crtc.dev, &idx)) {
		send_pending_event(pipeline);
		return;
	}

	/*
	 * Send page flip request to the backend *after* we have event cached
	 * above, so on page flip done event from the backend we can
	 * deliver it and there is no race condition between this code and
	 * event from the backend.
	 * If this is not a page flip, e.g. no flip done event from the backend
	 * is expected, then send now.
	 */
	if (!display_send_page_flip(pipe, old_plane_state))
		send_pending_event(pipeline);

	drm_dev_exit(idx);
}

static enum drm_mode_status
display_mode_valid(struct drm_simple_display_pipe *pipe,
		   const struct drm_display_mode *mode)
{
	struct xen_drm_front_drm_pipeline *pipeline =
			container_of(pipe, struct xen_drm_front_drm_pipeline,
				     pipe);

	if (mode->hdisplay != pipeline->width)
		return MODE_ERROR;

Annotation

Implementation Notes