File Index
Files and directories
Sign in
FILE

armada_fb.c

File preview with syntax highlighting.

linux-6.19.14/drivers/gpu/drm/armada/armada_fb.c C
  1// SPDX-License-Identifier: GPL-2.0-only
  2/*
  3 * Copyright (C) 2012 Russell King
  4 */
  5
  6#include <drm/drm_modeset_helper.h>
  7#include <drm/drm_fourcc.h>
  8#include <drm/drm_gem_framebuffer_helper.h>
  9#include <drm/drm_print.h>
 10
 11#include "armada_drm.h"
 12#include "armada_fb.h"
 13#include "armada_gem.h"
 14#include "armada_hw.h"
 15
 16static const struct drm_framebuffer_funcs armada_fb_funcs = {
 17	.destroy	= drm_gem_fb_destroy,
 18	.create_handle	= drm_gem_fb_create_handle,
 19};
 20
 21struct armada_framebuffer *armada_framebuffer_create(struct drm_device *dev,
 22						     const struct drm_format_info *info,
 23						     const struct drm_mode_fb_cmd2 *mode,
 24						     struct armada_gem_object *obj)
 25{
 26	struct armada_framebuffer *dfb;
 27	uint8_t format, config;
 28	int ret;
 29
 30	switch (mode->pixel_format) {
 31#define FMT(drm, fmt, mod)		\
 32	case DRM_FORMAT_##drm:		\
 33		format = CFG_##fmt;	\
 34		config = mod;		\
 35		break
 36	FMT(RGB565,	565,		CFG_SWAPRB);
 37	FMT(BGR565,	565,		0);
 38	FMT(ARGB1555,	1555,		CFG_SWAPRB);
 39	FMT(ABGR1555,	1555,		0);
 40	FMT(RGB888,	888PACK,	CFG_SWAPRB);
 41	FMT(BGR888,	888PACK,	0);
 42	FMT(XRGB8888,	X888,		CFG_SWAPRB);
 43	FMT(XBGR8888,	X888,		0);
 44	FMT(ARGB8888,	8888,		CFG_SWAPRB);
 45	FMT(ABGR8888,	8888,		0);
 46	FMT(YUYV,	422PACK,	CFG_YUV2RGB | CFG_SWAPYU | CFG_SWAPUV);
 47	FMT(UYVY,	422PACK,	CFG_YUV2RGB);
 48	FMT(VYUY,	422PACK,	CFG_YUV2RGB | CFG_SWAPUV);
 49	FMT(YVYU,	422PACK,	CFG_YUV2RGB | CFG_SWAPYU);
 50	FMT(YUV422,	422,		CFG_YUV2RGB);
 51	FMT(YVU422,	422,		CFG_YUV2RGB | CFG_SWAPUV);
 52	FMT(YUV420,	420,		CFG_YUV2RGB);
 53	FMT(YVU420,	420,		CFG_YUV2RGB | CFG_SWAPUV);
 54	FMT(C8,		PSEUDO8,	0);
 55#undef FMT
 56	default:
 57		return ERR_PTR(-EINVAL);
 58	}
 59
 60	dfb = kzalloc(sizeof(*dfb), GFP_KERNEL);
 61	if (!dfb) {
 62		DRM_ERROR("failed to allocate Armada fb object\n");
 63		return ERR_PTR(-ENOMEM);
 64	}
 65
 66	dfb->fmt = format;
 67	dfb->mod = config;
 68	dfb->fb.obj[0] = &obj->obj;
 69
 70	drm_helper_mode_fill_fb_struct(dev, &dfb->fb, info, mode);
 71
 72	ret = drm_framebuffer_init(dev, &dfb->fb, &armada_fb_funcs);
 73	if (ret) {
 74		kfree(dfb);
 75		return ERR_PTR(ret);
 76	}
 77
 78	/*
 79	 * Take a reference on our object as we're successful - the
 80	 * caller already holds a reference, which keeps us safe for
 81	 * the above call, but the caller will drop their reference
 82	 * to it.  Hence we need to take our own reference.
 83	 */
 84	drm_gem_object_get(&obj->obj);
 85
 86	return dfb;
 87}
 88
 89struct drm_framebuffer *armada_fb_create(struct drm_device *dev,
 90	struct drm_file *dfile, const struct drm_format_info *info,
 91	const struct drm_mode_fb_cmd2 *mode)
 92{
 93	struct armada_gem_object *obj;
 94	struct armada_framebuffer *dfb;
 95	int ret;
 96
 97	DRM_DEBUG_DRIVER("w%u h%u pf%08x f%u p%u,%u,%u\n",
 98		mode->width, mode->height, mode->pixel_format,
 99		mode->flags, mode->pitches[0], mode->pitches[1],
100		mode->pitches[2]);
101
102	/* We can only handle a single plane at the moment */
103	if (info->num_planes > 1 &&
104	    (mode->handles[0] != mode->handles[1] ||
105	     mode->handles[0] != mode->handles[2])) {
106		ret = -EINVAL;
107		goto err;
108	}
109
110	obj = armada_gem_object_lookup(dfile, mode->handles[0]);
111	if (!obj) {
112		ret = -ENOENT;
113		goto err;
114	}
115
116	if (obj->obj.import_attach && !obj->sgt) {
117		ret = armada_gem_map_import(obj);
118		if (ret)
119			goto err_unref;
120	}
121
122	/* Framebuffer objects must have a valid device address for scanout */
123	if (!obj->mapped) {
124		ret = -EINVAL;
125		goto err_unref;
126	}
127
128	dfb = armada_framebuffer_create(dev, info, mode, obj);
129	if (IS_ERR(dfb)) {
130		ret = PTR_ERR(dfb);
131		goto err;
132	}
133
134	drm_gem_object_put(&obj->obj);
135
136	return &dfb->fb;
137
138 err_unref:
139	drm_gem_object_put(&obj->obj);
140 err:
141	DRM_ERROR("failed to initialize framebuffer: %d\n", ret);
142	return ERR_PTR(ret);
143}
~/ Read-only file preview.