drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/hisilicon/kirin/kirin_drm_drv.c
Extension
.c
Size
7913 bytes
Lines
321
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

struct kirin_drm_private {
	struct kirin_crtc crtc;
	struct kirin_plane planes[KIRIN_MAX_PLANE];
	void *hw_ctx;
};

static int kirin_drm_crtc_init(struct drm_device *dev, struct drm_crtc *crtc,
			       struct drm_plane *plane,
			       const struct kirin_drm_data *driver_data)
{
	struct device_node *port;
	int ret;

	/* set crtc port so that
	 * drm_of_find_possible_crtcs call works
	 */
	port = of_get_child_by_name(dev->dev->of_node, "port");
	if (!port) {
		DRM_ERROR("no port node found in %pOF\n", dev->dev->of_node);
		return -EINVAL;
	}
	of_node_put(port);
	crtc->port = port;

	ret = drm_crtc_init_with_planes(dev, crtc, plane, NULL,
					driver_data->crtc_funcs, NULL);
	if (ret) {
		DRM_ERROR("failed to init crtc.\n");
		return ret;
	}

	drm_crtc_helper_add(crtc, driver_data->crtc_helper_funcs);

	return 0;
}

static int kirin_drm_plane_init(struct drm_device *dev, struct drm_plane *plane,
				enum drm_plane_type type,
				const struct kirin_drm_data *data)
{
	int ret = 0;

	ret = drm_universal_plane_init(dev, plane, 1, data->plane_funcs,
				       data->channel_formats,
				       data->channel_formats_cnt,
				       NULL, type, NULL);
	if (ret) {
		DRM_ERROR("fail to init plane, ch=%d\n", 0);
		return ret;
	}

	drm_plane_helper_add(plane, data->plane_helper_funcs);

	return 0;
}

static void kirin_drm_private_cleanup(struct drm_device *dev)
{
	struct kirin_drm_private *kirin_priv = dev->dev_private;
	struct kirin_drm_data *data;

	data = (struct kirin_drm_data *)of_device_get_match_data(dev->dev);
	if (data->cleanup_hw_ctx)
		data->cleanup_hw_ctx(kirin_priv->hw_ctx);

	devm_kfree(dev->dev, kirin_priv);
	dev->dev_private = NULL;
}

static int kirin_drm_private_init(struct drm_device *dev,
				  const struct kirin_drm_data *driver_data)
{
	struct platform_device *pdev = to_platform_device(dev->dev);
	struct kirin_drm_private *kirin_priv;
	struct drm_plane *prim_plane;
	enum drm_plane_type type;
	void *ctx;
	int ret;
	u32 ch;

	kirin_priv = devm_kzalloc(dev->dev, sizeof(*kirin_priv), GFP_KERNEL);
	if (!kirin_priv) {
		DRM_ERROR("failed to alloc kirin_drm_private\n");
		return -ENOMEM;
	}

	ctx = driver_data->alloc_hw_ctx(pdev, &kirin_priv->crtc.base);
	if (IS_ERR(ctx)) {
		DRM_ERROR("failed to initialize kirin_priv hw ctx\n");
		return -EINVAL;

Annotation

Implementation Notes