drivers/gpu/drm/logicvc/logicvc_crtc.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/logicvc/logicvc_crtc.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/logicvc/logicvc_crtc.c
Extension
.c
Size
8254 bytes
Lines
281
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+
/*
 * Copyright (C) 2019-2022 Bootlin
 * Author: Paul Kocialkowski <paul.kocialkowski@bootlin.com>
 */

#include <linux/of.h>
#include <linux/of_graph.h>
#include <linux/types.h>
#include <linux/workqueue.h>

#include <drm/drm_atomic_helper.h>
#include <drm/drm_crtc.h>
#include <drm/drm_drv.h>
#include <drm/drm_gem_dma_helper.h>
#include <drm/drm_print.h>
#include <drm/drm_vblank.h>

#include "logicvc_crtc.h"
#include "logicvc_drm.h"
#include "logicvc_interface.h"
#include "logicvc_layer.h"
#include "logicvc_regs.h"

#define logicvc_crtc(c) \
	container_of(c, struct logicvc_crtc, drm_crtc)

static enum drm_mode_status
logicvc_crtc_mode_valid(struct drm_crtc *drm_crtc,
			const struct drm_display_mode *mode)
{
	if (mode->flags & DRM_MODE_FLAG_INTERLACE)
		return -EINVAL;

	return 0;
}

static void logicvc_crtc_atomic_begin(struct drm_crtc *drm_crtc,
				      struct drm_atomic_commit *state)
{
	struct logicvc_crtc *crtc = logicvc_crtc(drm_crtc);
	struct drm_crtc_state *old_state =
		drm_atomic_get_old_crtc_state(state, drm_crtc);
	struct drm_device *drm_dev = drm_crtc->dev;
	unsigned long flags;

	/*
	 * We need to grab the pending event here if vblank was already enabled
	 * since we won't get a call to atomic_enable to grab it.
	 */
	if (drm_crtc->state->event && old_state->active) {
		spin_lock_irqsave(&drm_dev->event_lock, flags);
		WARN_ON(drm_crtc_vblank_get(drm_crtc) != 0);

		crtc->event = drm_crtc->state->event;
		drm_crtc->state->event = NULL;

		spin_unlock_irqrestore(&drm_dev->event_lock, flags);
	}
}

static void logicvc_crtc_atomic_enable(struct drm_crtc *drm_crtc,
				       struct drm_atomic_commit *state)
{
	struct logicvc_crtc *crtc = logicvc_crtc(drm_crtc);
	struct logicvc_drm *logicvc = logicvc_drm(drm_crtc->dev);
	struct drm_crtc_state *old_state =
		drm_atomic_get_old_crtc_state(state, drm_crtc);
	struct drm_crtc_state *new_state =
		drm_atomic_get_new_crtc_state(state, drm_crtc);
	struct drm_display_mode *mode = &new_state->adjusted_mode;

	struct drm_device *drm_dev = drm_crtc->dev;
	unsigned int hact, hfp, hsl, hbp;
	unsigned int vact, vfp, vsl, vbp;
	unsigned long flags;
	u32 ctrl;

	/* Timings */

	hact = mode->hdisplay;
	hfp = mode->hsync_start - mode->hdisplay;
	hsl = mode->hsync_end - mode->hsync_start;
	hbp = mode->htotal - mode->hsync_end;

	vact = mode->vdisplay;
	vfp = mode->vsync_start - mode->vdisplay;
	vsl = mode->vsync_end - mode->vsync_start;
	vbp = mode->vtotal - mode->vsync_end;

Annotation

Implementation Notes