Commit 6a0f9ebf authored by Ville Syrjälä's avatar Ville Syrjälä
Browse files

drm: Add mode_config .get_format_info() hook



Allow drivers to return a custom drm_format_info structure for special
fb layouts. We'll use this for the compression control surface in i915.

v2: Fix drm_get_format_info() kernel doc (Laurent)
    Don't pass 'dev' to the new hook (Laurent)
v3: s/compresssion/compression/ (Ben)

Cc: Laurent Pinchart <laurent.pinchart@ideasonboard.com>
Cc: Ben Widawsky <ben@bwidawsk.net>
Cc: Jason Ekstrand <jason@jlekstrand.net>
Signed-off-by: default avatarVille Syrjälä <ville.syrjala@linux.intel.com>
Reviewed-by: default avatarBen Widawsky <ben@bwidawsk.net>
Link: http://patchwork.freedesktop.org/patch/msgid/20170321181218.10042-4-ville.syrjala@linux.intel.com
parent 33f673aa
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -177,7 +177,7 @@ struct drm_framebuffer *drm_fb_cma_create_with_funcs(struct drm_device *dev,
	int ret;
	int i;

	info = drm_format_info(mode_cmd->pixel_format);
	info = drm_get_format_info(dev, mode_cmd);
	if (!info)
		return ERR_PTR(-EINVAL);

+25 −0
Original line number Diff line number Diff line
@@ -198,6 +198,31 @@ const struct drm_format_info *drm_format_info(u32 format)
}
EXPORT_SYMBOL(drm_format_info);

/**
 * drm_get_format_info - query information for a given framebuffer configuration
 * @dev: DRM device
 * @mode_cmd: metadata from the userspace fb creation request
 *
 * Returns:
 * The instance of struct drm_format_info that describes the pixel format, or
 * NULL if the format is unsupported.
 */
const struct drm_format_info *
drm_get_format_info(struct drm_device *dev,
		    const struct drm_mode_fb_cmd2 *mode_cmd)
{
	const struct drm_format_info *info = NULL;

	if (dev->mode_config.funcs->get_format_info)
		info = dev->mode_config.funcs->get_format_info(mode_cmd);

	if (!info)
		info = drm_format_info(mode_cmd->pixel_format);

	return info;
}
EXPORT_SYMBOL(drm_get_format_info);

/**
 * drm_format_num_planes - get the number of planes for format
 * @format: pixel format (DRM_FORMAT_*)
+7 −2
Original line number Diff line number Diff line
@@ -144,11 +144,13 @@ static int fb_plane_height(int height,
	return DIV_ROUND_UP(height, format->vsub);
}

static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
static int framebuffer_check(struct drm_device *dev,
			     const struct drm_mode_fb_cmd2 *r)
{
	const struct drm_format_info *info;
	int i;

	/* check if the format is supported at all */
	info = __drm_format_info(r->pixel_format & ~DRM_FORMAT_BIG_ENDIAN);
	if (!info) {
		struct drm_format_name_buf format_name;
@@ -158,6 +160,9 @@ static int framebuffer_check(const struct drm_mode_fb_cmd2 *r)
		return -EINVAL;
	}

	/* now let the driver pick its own format info */
	info = drm_get_format_info(dev, r);

	if (r->width == 0) {
		DRM_DEBUG_KMS("bad framebuffer width %u\n", r->width);
		return -EINVAL;
@@ -281,7 +286,7 @@ drm_internal_framebuffer_create(struct drm_device *dev,
		return ERR_PTR(-EINVAL);
	}

	ret = framebuffer_check(r);
	ret = framebuffer_check(dev, r);
	if (ret)
		return ERR_PTR(ret);

+1 −1
Original line number Diff line number Diff line
@@ -78,7 +78,7 @@ void drm_helper_mode_fill_fb_struct(struct drm_device *dev,
	int i;

	fb->dev = dev;
	fb->format = drm_format_info(mode_cmd->pixel_format);
	fb->format = drm_get_format_info(dev, mode_cmd);
	fb->width = mode_cmd->width;
	fb->height = mode_cmd->height;
	for (i = 0; i < 4; i++) {
+6 −0
Original line number Diff line number Diff line
@@ -25,6 +25,9 @@
#include <linux/types.h>
#include <uapi/drm/drm_fourcc.h>

struct drm_device;
struct drm_mode_fb_cmd2;

/**
 * struct drm_format_info - information about a DRM format
 * @format: 4CC format identifier (DRM_FORMAT_*)
@@ -55,6 +58,9 @@ struct drm_format_name_buf {

const struct drm_format_info *__drm_format_info(u32 format);
const struct drm_format_info *drm_format_info(u32 format);
const struct drm_format_info *
drm_get_format_info(struct drm_device *dev,
		    const struct drm_mode_fb_cmd2 *mode_cmd);
uint32_t drm_mode_legacy_fb_format(uint32_t bpp, uint32_t depth);
int drm_format_num_planes(uint32_t format);
int drm_format_plane_cpp(uint32_t format, int plane);
Loading