Esempio n. 1
0
static struct drm_framebuffer *
rockchip_user_fb_create(struct drm_device *dev, struct drm_file *file_priv,
			const struct drm_mode_fb_cmd2 *mode_cmd)
{
	struct drm_framebuffer *fb;
	struct drm_gem_object *objs[ROCKCHIP_MAX_FB_BUFFER];
	struct drm_gem_object *obj;
	unsigned int hsub;
	unsigned int vsub;
	int num_planes;
	int ret;
	int i;

	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);
	num_planes = min(drm_format_num_planes(mode_cmd->pixel_format),
			 ROCKCHIP_MAX_FB_BUFFER);

	for (i = 0; i < num_planes; i++) {
		unsigned int width = mode_cmd->width / (i ? hsub : 1);
		unsigned int height = mode_cmd->height / (i ? vsub : 1);
		unsigned int min_size;

		obj = drm_gem_object_lookup(file_priv, mode_cmd->handles[i]);
		if (!obj) {
			DRM_DEV_ERROR(dev->dev,
				      "Failed to lookup GEM object\n");
			ret = -ENXIO;
			goto err_gem_object_unreference;
		}

		min_size = (height - 1) * mode_cmd->pitches[i] +
			mode_cmd->offsets[i] +
			width * drm_format_plane_cpp(mode_cmd->pixel_format, i);

		if (obj->size < min_size) {
			drm_gem_object_put_unlocked(obj);
			ret = -EINVAL;
			goto err_gem_object_unreference;
		}
		objs[i] = obj;
	}

	fb = rockchip_fb_alloc(dev, mode_cmd, objs, i);
	if (IS_ERR(fb)) {
		ret = PTR_ERR(fb);
		goto err_gem_object_unreference;
	}

	return fb;

err_gem_object_unreference:
	for (i--; i >= 0; i--)
		drm_gem_object_put_unlocked(objs[i]);
	return ERR_PTR(ret);
}
Esempio n. 2
0
/**
 * drm_format_plane_height - height of the plane given the first plane
 * @height: height of the first plane
 * @format: pixel format
 * @plane: plane index
 *
 * Returns:
 * The height of @plane, given that the height of the first plane is @height.
 */
int drm_format_plane_height(int height, uint32_t format, int plane)
{
	if (plane >= drm_format_num_planes(format))
		return 0;

	if (plane == 0)
		return height;

	return height / drm_format_vert_chroma_subsampling(format);
}
Esempio n. 3
0
struct drm_framebuffer *tegra_fb_create(struct drm_device *drm,
					struct drm_file *file,
					const struct drm_mode_fb_cmd2 *cmd)
{
	unsigned int hsub, vsub, i;
	struct tegra_bo *planes[4];
	struct drm_gem_object *gem;
	struct tegra_fb *fb;
	int err;

	hsub = drm_format_horz_chroma_subsampling(cmd->pixel_format);
	vsub = drm_format_vert_chroma_subsampling(cmd->pixel_format);

	for (i = 0; i < drm_format_num_planes(cmd->pixel_format); i++) {
		unsigned int width = cmd->width / (i ? hsub : 1);
		unsigned int height = cmd->height / (i ? vsub : 1);
		unsigned int size, bpp;

		gem = drm_gem_object_lookup(file, cmd->handles[i]);
		if (!gem) {
			err = -ENXIO;
			goto unreference;
		}

		bpp = drm_format_plane_cpp(cmd->pixel_format, i);

		size = (height - 1) * cmd->pitches[i] +
		       width * bpp + cmd->offsets[i];

		if (gem->size < size) {
			err = -EINVAL;
			goto unreference;
		}

		planes[i] = to_tegra_bo(gem);
	}

	fb = tegra_fb_alloc(drm, cmd, planes, i);
	if (IS_ERR(fb)) {
		err = PTR_ERR(fb);
		goto unreference;
	}

	return &fb->base;

unreference:
	while (i--)
		drm_gem_object_put_unlocked(&planes[i]->gem);

	return ERR_PTR(err);
}
struct drm_framebuffer *mtk_drm_mode_fb_create(struct drm_device *dev,
					       struct drm_file *file,
					       struct drm_mode_fb_cmd2 *cmd)
{
	unsigned int hsub, vsub, i;
	struct mtk_drm_fb *mtk_fb;
	struct drm_gem_object *gem[MAX_FB_OBJ];
	int err;

	hsub = drm_format_horz_chroma_subsampling(cmd->pixel_format);
	vsub = drm_format_vert_chroma_subsampling(cmd->pixel_format);
	for (i = 0; i < drm_format_num_planes(cmd->pixel_format); i++) {
		unsigned int width = cmd->width / (i ? hsub : 1);
		unsigned int height = cmd->height / (i ? vsub : 1);
		unsigned int size, bpp;

		gem[i] = drm_gem_object_lookup(dev, file, cmd->handles[i]);
		if (!gem[i]) {
			err = -ENOENT;
			goto unreference;
		}

		bpp = drm_format_plane_cpp(cmd->pixel_format, i);
		size = (height - 1) * cmd->pitches[i] + width * bpp;
		size += cmd->offsets[i];

		if (gem[i]->size < size) {
			err = -EINVAL;
			goto unreference;
		}
	}

	mtk_fb = mtk_drm_framebuffer_init(dev, cmd, gem);

	return &mtk_fb->base;

unreference:
	while (i--)
		drm_gem_object_unreference_unlocked(gem[i]);

	return ERR_PTR(err);
}
Esempio n. 5
0
/* mode set a plane */
int xilinx_drm_plane_mode_set(struct drm_plane *base_plane,
			      struct drm_framebuffer *fb,
			      int crtc_x, int crtc_y,
			      unsigned int crtc_w, unsigned int crtc_h,
			      uint32_t src_x, uint32_t src_y,
			      uint32_t src_w, uint32_t src_h)
{
	struct xilinx_drm_plane *plane = to_xilinx_plane(base_plane);
	struct drm_gem_cma_object *obj;
	size_t offset;
	unsigned int hsub, vsub, i;

	DRM_DEBUG_KMS("plane->id: %d\n", plane->id);

	if (fb->pixel_format != plane->format) {
		DRM_ERROR("unsupported pixel format %08x\n", fb->pixel_format);
		return -EINVAL;
	}

	/* configure cresample */
	if (plane->cresample)
		xilinx_cresample_configure(plane->cresample, crtc_w, crtc_h);

	/* configure rgb2yuv */
	if (plane->rgb2yuv)
		xilinx_rgb2yuv_configure(plane->rgb2yuv, crtc_w, crtc_h);

	DRM_DEBUG_KMS("h: %d(%d), v: %d(%d)\n",
			src_w, crtc_x, src_h, crtc_y);
	DRM_DEBUG_KMS("bpp: %d\n", fb->bits_per_pixel / 8);

	hsub = drm_format_horz_chroma_subsampling(fb->pixel_format);
	vsub = drm_format_vert_chroma_subsampling(fb->pixel_format);

	for (i = 0; i < drm_format_num_planes(fb->pixel_format); i++) {
		unsigned int width = src_w / (i ? hsub : 1);
		unsigned int height = src_h / (i ? vsub : 1);
		unsigned int cpp = drm_format_plane_cpp(fb->pixel_format, i);

		obj = xilinx_drm_fb_get_gem_obj(fb, i);
		if (!obj) {
			DRM_ERROR("failed to get a gem obj for fb\n");
			return -EINVAL;
		}

		plane->dma[i].xt.numf = height;
		plane->dma[i].sgl[0].size = width * cpp;
		plane->dma[i].sgl[0].icg = fb->pitches[i] -
					   plane->dma[i].sgl[0].size;
		offset = src_x * cpp + src_y * fb->pitches[i];
		offset += fb->offsets[i];
		plane->dma[i].xt.src_start = obj->paddr + offset;
		plane->dma[i].xt.frame_size = 1;
		plane->dma[i].xt.dir = DMA_MEM_TO_DEV;
		plane->dma[i].xt.src_sgl = true;
		plane->dma[i].xt.dst_sgl = false;
		plane->dma[i].is_active = true;
	}

	for (; i < MAX_NUM_SUB_PLANES; i++)
		plane->dma[i].is_active = false;

	/* set OSD dimensions */
	if (plane->manager->osd) {
		xilinx_osd_disable_rue(plane->manager->osd);

		xilinx_osd_layer_set_dimension(plane->osd_layer, crtc_x, crtc_y,
					       src_w, src_h);

		xilinx_osd_enable_rue(plane->manager->osd);
	}

	if (plane->manager->dp_sub) {
		int ret;

		ret = xilinx_drm_dp_sub_layer_check_size(plane->manager->dp_sub,
							 plane->dp_layer,
							 src_w, src_h);
		if (ret)
			return ret;
	}

	return 0;
}
Esempio n. 6
0
struct drm_framebuffer *msm_framebuffer_init(struct drm_device *dev,
		const struct drm_mode_fb_cmd2 *mode_cmd, struct drm_gem_object **bos)
{
	struct msm_drm_private *priv = dev->dev_private;
	struct msm_kms *kms = priv->kms;
	struct msm_framebuffer *msm_fb = NULL;
	struct drm_framebuffer *fb;
	const struct msm_format *format;
	int ret, i, n;
	unsigned int hsub, vsub;

	DBG("create framebuffer: dev=%p, mode_cmd=%p (%dx%d@%4.4s)",
			dev, mode_cmd, mode_cmd->width, mode_cmd->height,
			(char *)&mode_cmd->pixel_format);

	n = drm_format_num_planes(mode_cmd->pixel_format);
	hsub = drm_format_horz_chroma_subsampling(mode_cmd->pixel_format);
	vsub = drm_format_vert_chroma_subsampling(mode_cmd->pixel_format);

	format = kms->funcs->get_format(kms, mode_cmd->pixel_format);
	if (!format) {
		dev_err(dev->dev, "unsupported pixel format: %4.4s\n",
				(char *)&mode_cmd->pixel_format);
		ret = -EINVAL;
		goto fail;
	}

	msm_fb = kzalloc(sizeof(*msm_fb), GFP_KERNEL);
	if (!msm_fb) {
		ret = -ENOMEM;
		goto fail;
	}

	fb = &msm_fb->base;

	msm_fb->format = format;

	if (n > ARRAY_SIZE(msm_fb->planes)) {
		ret = -EINVAL;
		goto fail;
	}

	for (i = 0; i < n; i++) {
		unsigned int width = mode_cmd->width / (i ? hsub : 1);
		unsigned int height = mode_cmd->height / (i ? vsub : 1);
		unsigned int min_size;

		min_size = (height - 1) * mode_cmd->pitches[i]
			 + width * drm_format_plane_cpp(mode_cmd->pixel_format, i)
			 + mode_cmd->offsets[i];

		if (bos[i]->size < min_size) {
			ret = -EINVAL;
			goto fail;
		}

		msm_fb->planes[i] = bos[i];
	}

	drm_helper_mode_fill_fb_struct(fb, mode_cmd);

	ret = drm_framebuffer_init(dev, fb, &msm_framebuffer_funcs);
	if (ret) {
		dev_err(dev->dev, "framebuffer init failed: %d\n", ret);
		goto fail;
	}

	DBG("create: FB ID: %d (%p)", fb->base.id, fb);

	return fb;

fail:
	kfree(msm_fb);

	return ERR_PTR(ret);
}