Пример #1
0
static void ade_rdma_set(void __iomem *base, struct drm_framebuffer *fb,
			 u32 ch, u32 y, u32 in_h, u32 fmt)
{
	struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, 0);
	struct drm_format_name_buf format_name;
	u32 reg_ctrl, reg_addr, reg_size, reg_stride, reg_space, reg_en;
	u32 stride = fb->pitches[0];
	u32 addr = (u32)obj->paddr + y * stride;

	DRM_DEBUG_DRIVER("rdma%d: (y=%d, height=%d), stride=%d, paddr=0x%x\n",
			 ch + 1, y, in_h, stride, (u32)obj->paddr);
	DRM_DEBUG_DRIVER("addr=0x%x, fb:%dx%d, pixel_format=%d(%s)\n",
			 addr, fb->width, fb->height, fmt,
			 drm_get_format_name(fb->pixel_format, &format_name));

	/* get reg offset */
	reg_ctrl = RD_CH_CTRL(ch);
	reg_addr = RD_CH_ADDR(ch);
	reg_size = RD_CH_SIZE(ch);
	reg_stride = RD_CH_STRIDE(ch);
	reg_space = RD_CH_SPACE(ch);
	reg_en = RD_CH_EN(ch);

	/*
	 * TODO: set rotation
	 */
	writel((fmt << 16) & 0x1f0000, base + reg_ctrl);
	writel(addr, base + reg_addr);
	writel((in_h << 16) | stride, base + reg_size);
	writel(stride, base + reg_stride);
	writel(in_h * stride, base + reg_space);
	writel(ADE_ENABLE, base + reg_en);
	ade_update_reload_bit(base, RDMA_OFST + ch, 0);
}
Пример #2
0
/**
 * drm_atomic_plane_check - check plane state
 * @plane: plane to check
 * @state: plane state to check
 *
 * Provides core sanity checks for plane state.
 *
 * RETURNS:
 * Zero on success, error code on failure
 */
static int drm_atomic_plane_check(struct drm_plane *plane,
		struct drm_plane_state *state)
{
	unsigned int fb_width, fb_height;
	int ret;

	/* either *both* CRTC and FB must be set, or neither */
	if (WARN_ON(state->crtc && !state->fb)) {
		DRM_DEBUG_ATOMIC("CRTC set but no FB\n");
		return -EINVAL;
	} else if (WARN_ON(state->fb && !state->crtc)) {
		DRM_DEBUG_ATOMIC("FB set but no CRTC\n");
		return -EINVAL;
	}

	/* if disabled, we don't care about the rest of the state: */
	if (!state->crtc)
		return 0;

	/* Check whether this plane is usable on this CRTC */
	if (!(plane->possible_crtcs & drm_crtc_mask(state->crtc))) {
		DRM_DEBUG_ATOMIC("Invalid crtc for plane\n");
		return -EINVAL;
	}

	/* Check whether this plane supports the fb pixel format. */
	ret = drm_plane_check_pixel_format(plane, state->fb->pixel_format);
	if (ret) {
		DRM_DEBUG_ATOMIC("Invalid pixel format %s\n",
				 drm_get_format_name(state->fb->pixel_format));
		return ret;
	}

	/* Give drivers some help against integer overflows */
	if (state->crtc_w > INT_MAX ||
	    state->crtc_x > INT_MAX - (int32_t) state->crtc_w ||
	    state->crtc_h > INT_MAX ||
	    state->crtc_y > INT_MAX - (int32_t) state->crtc_h) {
		DRM_DEBUG_ATOMIC("Invalid CRTC coordinates %ux%u+%d+%d\n",
				 state->crtc_w, state->crtc_h,
				 state->crtc_x, state->crtc_y);
		return -ERANGE;
	}

	fb_width = state->fb->width << 16;
	fb_height = state->fb->height << 16;

	/* Make sure source coordinates are inside the fb. */
	if (state->src_w > fb_width ||
	    state->src_x > fb_width - state->src_w ||
	    state->src_h > fb_height ||
	    state->src_y > fb_height - state->src_h) {
		DRM_DEBUG_ATOMIC("Invalid source coordinates "
				 "%u.%06ux%u.%06u+%u.%06u+%u.%06u\n",
				 state->src_w >> 16, ((state->src_w & 0xffff) * 15625) >> 10,
				 state->src_h >> 16, ((state->src_h & 0xffff) * 15625) >> 10,
				 state->src_x >> 16, ((state->src_x & 0xffff) * 15625) >> 10,
				 state->src_y >> 16, ((state->src_y & 0xffff) * 15625) >> 10);
		return -ENOSPC;
	}
Пример #3
0
static int tinydrm_fbdev_create(struct drm_fb_helper *helper,
				struct drm_fb_helper_surface_size *sizes)
{
	struct tinydrm_device *tdev = drm_to_tinydrm(helper->dev);
	int ret;

	ret = drm_fbdev_cma_create_with_funcs(helper, sizes, tdev->fb_funcs);
	if (ret)
		return ret;

	strncpy(helper->fbdev->fix.id, helper->dev->driver->name, 16);
	tdev->fbdev_helper = helper;

	if (fbdefio_delay) {
		unsigned long delay;

		delay = msecs_to_jiffies(fbdefio_delay);
		helper->fbdev->fbdefio->delay = delay ? delay : 1;
	}

	DRM_DEBUG_KMS("fbdev: [FB:%d] pixel_format=%s, fbdefio->delay=%ums\n",
		      helper->fb->base.id,
		      drm_get_format_name(helper->fb->pixel_format),
		      jiffies_to_msecs(helper->fbdev->fbdefio->delay));

	return 0;
}
Пример #4
0
static int
malidp_mw_encoder_atomic_check(struct drm_encoder *encoder,
			       struct drm_crtc_state *crtc_state,
			       struct drm_connector_state *conn_state)
{
	struct malidp_mw_connector_state *mw_state = to_mw_state(conn_state);
	struct malidp_drm *malidp = encoder->dev->dev_private;
	struct drm_framebuffer *fb;
	int i, n_planes;

	if (!conn_state->writeback_job || !conn_state->writeback_job->fb)
		return 0;

	fb = conn_state->writeback_job->fb;
	if ((fb->width != crtc_state->mode.hdisplay) ||
	    (fb->height != crtc_state->mode.vdisplay)) {
		DRM_DEBUG_KMS("Invalid framebuffer size %ux%u\n",
				fb->width, fb->height);
		return -EINVAL;
	}

	if (fb->modifier) {
		DRM_DEBUG_KMS("Writeback framebuffer does not support modifiers\n");
		return -EINVAL;
	}

	mw_state->format =
		malidp_hw_get_format_id(&malidp->dev->hw->map, SE_MEMWRITE,
					fb->format->format, !!fb->modifier);
	if (mw_state->format == MALIDP_INVALID_FORMAT_ID) {
		struct drm_format_name_buf format_name;

		DRM_DEBUG_KMS("Invalid pixel format %s\n",
			      drm_get_format_name(fb->format->format,
						  &format_name));
		return -EINVAL;
	}

	n_planes = drm_format_num_planes(fb->format->format);
	for (i = 0; i < n_planes; i++) {
		struct drm_gem_cma_object *obj = drm_fb_cma_get_gem_obj(fb, i);
		/* memory write buffers are never rotated */
		u8 alignment = malidp_hw_get_pitch_align(malidp->dev, 0);

		if (fb->pitches[i] & (alignment - 1)) {
			DRM_DEBUG_KMS("Invalid pitch %u for plane %d\n",
				      fb->pitches[i], i);
			return -EINVAL;
		}
		mw_state->pitches[i] = fb->pitches[i];
		mw_state->addrs[i] = obj->paddr + fb->offsets[i];
	}
	mw_state->n_planes = n_planes;

	if (fb->format->is_yuv)
		mw_state->rgb2yuv_coeffs = rgb2yuv_coeffs_bt709_limited;

	return 0;
}
Пример #5
0
/**
 * tinydrm_fb_create - tinydrm .fb_create() helper
 * @drm: DRM device
 * @file_priv: DRM file info
 * @mode_cmd: metadata from the userspace fb creation request
 *
 * Helper for the &drm_mode_config_funcs->fb_create callback.
 * It sets up a &drm_framebuffer backed by the &drm_gem_cma_object buffer
 * object provided in @mode_cmd.
 */
struct drm_framebuffer *
tinydrm_fb_create(struct drm_device *drm, struct drm_file *file_priv,
		  const struct drm_mode_fb_cmd2 *mode_cmd)
{
	struct tinydrm_device *tdev = drm_to_tinydrm(drm);
	struct drm_framebuffer *fb;

	fb = drm_fb_cma_create_with_funcs(drm, file_priv, mode_cmd,
					  tdev->fb_funcs);
	if (!IS_ERR(fb))
		DRM_DEBUG_KMS("[FB:%d] pixel_format: %s\n", fb->base.id,
			      drm_get_format_name(fb->pixel_format));

	return fb;
}
Пример #6
0
static int __setplane_check(struct drm_plane *plane,
			    struct drm_crtc *crtc,
			    struct drm_framebuffer *fb,
			    int32_t crtc_x, int32_t crtc_y,
			    uint32_t crtc_w, uint32_t crtc_h,
			    uint32_t src_x, uint32_t src_y,
			    uint32_t src_w, uint32_t src_h)
{
	int ret;

	/* Check whether this plane is usable on this CRTC */
	if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
		DRM_DEBUG_KMS("Invalid crtc for plane\n");
		return -EINVAL;
	}

	/* Check whether this plane supports the fb pixel format. */
	ret = drm_plane_check_pixel_format(plane, fb->format->format,
					   fb->modifier);
	if (ret) {
		struct drm_format_name_buf format_name;

		DRM_DEBUG_KMS("Invalid pixel format %s, modifier 0x%llx\n",
			      drm_get_format_name(fb->format->format,
						  &format_name),
			      fb->modifier);
		return ret;
	}

	/* Give drivers some help against integer overflows */
	if (crtc_w > INT_MAX ||
	    crtc_x > INT_MAX - (int32_t) crtc_w ||
	    crtc_h > INT_MAX ||
	    crtc_y > INT_MAX - (int32_t) crtc_h) {
		DRM_DEBUG_KMS("Invalid CRTC coordinates %ux%u+%d+%d\n",
			      crtc_w, crtc_h, crtc_x, crtc_y);
		return -ERANGE;
	}

	ret = drm_framebuffer_check_src_coords(src_x, src_y, src_w, src_h, fb);
	if (ret)
		return ret;

	return 0;
}
Пример #7
0
static int intel_plane_atomic_check(struct drm_plane *plane,
				    struct drm_plane_state *state)
{
	struct drm_crtc *crtc = state->crtc;
	struct intel_crtc *intel_crtc;
	struct intel_crtc_state *crtc_state;
	struct intel_plane *intel_plane = to_intel_plane(plane);
	struct intel_plane_state *intel_state = to_intel_plane_state(state);
	struct drm_crtc_state *drm_crtc_state;
	int ret;

	crtc = crtc ? crtc : plane->state->crtc;
	intel_crtc = to_intel_crtc(crtc);

	/*
	 * Both crtc and plane->crtc could be NULL if we're updating a
	 * property while the plane is disabled.  We don't actually have
	 * anything driver-specific we need to test in that case, so
	 * just return success.
	 */
	if (!crtc)
		return 0;

	drm_crtc_state = drm_atomic_get_existing_crtc_state(state->state, crtc);
	if (WARN_ON(!drm_crtc_state))
		return -EINVAL;

	crtc_state = to_intel_crtc_state(drm_crtc_state);

	/*
	 * The original src/dest coordinates are stored in state->base, but
	 * we want to keep another copy internal to our driver that we can
	 * clip/modify ourselves.
	 */
	intel_state->src.x1 = state->src_x;
	intel_state->src.y1 = state->src_y;
	intel_state->src.x2 = state->src_x + state->src_w;
	intel_state->src.y2 = state->src_y + state->src_h;
	intel_state->dst.x1 = state->crtc_x;
	intel_state->dst.y1 = state->crtc_y;
	intel_state->dst.x2 = state->crtc_x + state->crtc_w;
	intel_state->dst.y2 = state->crtc_y + state->crtc_h;

	/* Clip all planes to CRTC size, or 0x0 if CRTC is disabled */
	intel_state->clip.x1 = 0;
	intel_state->clip.y1 = 0;
	intel_state->clip.x2 =
		crtc_state->base.enable ? crtc_state->pipe_src_w : 0;
	intel_state->clip.y2 =
		crtc_state->base.enable ? crtc_state->pipe_src_h : 0;

	if (state->fb && intel_rotation_90_or_270(state->rotation)) {
		if (!(state->fb->modifier[0] == I915_FORMAT_MOD_Y_TILED ||
			state->fb->modifier[0] == I915_FORMAT_MOD_Yf_TILED)) {
			DRM_DEBUG_KMS("Y/Yf tiling required for 90/270!\n");
			return -EINVAL;
		}

		/*
		 * 90/270 is not allowed with RGB64 16:16:16:16,
		 * RGB 16-bit 5:6:5, and Indexed 8-bit.
		 * TBD: Add RGB64 case once its added in supported format list.
		 */
		switch (state->fb->pixel_format) {
		case DRM_FORMAT_C8:
		case DRM_FORMAT_RGB565:
			DRM_DEBUG_KMS("Unsupported pixel format %s for 90/270!\n",
					drm_get_format_name(state->fb->pixel_format));
			return -EINVAL;

		default:
			break;
		}
	}

	intel_state->visible = false;
	ret = intel_plane->check_plane(plane, crtc_state, intel_state);
	if (ret)
		return ret;

	return intel_plane_atomic_calc_changes(&crtc_state->base, state);
}
Пример #8
0
/**
 * drm_atomic_plane_check - check plane state
 * @old_plane_state: old plane state to check
 * @new_plane_state: new plane state to check
 *
 * Provides core sanity checks for plane state.
 *
 * RETURNS:
 * Zero on success, error code on failure
 */
static int drm_atomic_plane_check(const struct drm_plane_state *old_plane_state,
				  const struct drm_plane_state *new_plane_state)
{
	struct drm_plane *plane = new_plane_state->plane;
	struct drm_crtc *crtc = new_plane_state->crtc;
	const struct drm_framebuffer *fb = new_plane_state->fb;
	unsigned int fb_width, fb_height;
	struct drm_mode_rect *clips;
	uint32_t num_clips;
	int ret;

	/* either *both* CRTC and FB must be set, or neither */
	if (crtc && !fb) {
		DRM_DEBUG_ATOMIC("[PLANE:%d:%s] CRTC set but no FB\n",
				 plane->base.id, plane->name);
		return -EINVAL;
	} else if (fb && !crtc) {
		DRM_DEBUG_ATOMIC("[PLANE:%d:%s] FB set but no CRTC\n",
				 plane->base.id, plane->name);
		return -EINVAL;
	}

	/* if disabled, we don't care about the rest of the state: */
	if (!crtc)
		return 0;

	/* Check whether this plane is usable on this CRTC */
	if (!(plane->possible_crtcs & drm_crtc_mask(crtc))) {
		DRM_DEBUG_ATOMIC("Invalid [CRTC:%d:%s] for [PLANE:%d:%s]\n",
				 crtc->base.id, crtc->name,
				 plane->base.id, plane->name);
		return -EINVAL;
	}

	/* Check whether this plane supports the fb pixel format. */
	ret = drm_plane_check_pixel_format(plane, fb->format->format,
					   fb->modifier);
	if (ret) {
		struct drm_format_name_buf format_name;
		DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid pixel format %s, modifier 0x%llx\n",
				 plane->base.id, plane->name,
				 drm_get_format_name(fb->format->format,
						     &format_name),
				 fb->modifier);
		return ret;
	}

	/* Give drivers some help against integer overflows */
	if (new_plane_state->crtc_w > INT_MAX ||
	    new_plane_state->crtc_x > INT_MAX - (int32_t) new_plane_state->crtc_w ||
	    new_plane_state->crtc_h > INT_MAX ||
	    new_plane_state->crtc_y > INT_MAX - (int32_t) new_plane_state->crtc_h) {
		DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid CRTC coordinates %ux%u+%d+%d\n",
				 plane->base.id, plane->name,
				 new_plane_state->crtc_w, new_plane_state->crtc_h,
				 new_plane_state->crtc_x, new_plane_state->crtc_y);
		return -ERANGE;
	}

	fb_width = fb->width << 16;
	fb_height = fb->height << 16;

	/* Make sure source coordinates are inside the fb. */
	if (new_plane_state->src_w > fb_width ||
	    new_plane_state->src_x > fb_width - new_plane_state->src_w ||
	    new_plane_state->src_h > fb_height ||
	    new_plane_state->src_y > fb_height - new_plane_state->src_h) {
		DRM_DEBUG_ATOMIC("[PLANE:%d:%s] invalid source coordinates "
				 "%u.%06ux%u.%06u+%u.%06u+%u.%06u (fb %ux%u)\n",
				 plane->base.id, plane->name,
				 new_plane_state->src_w >> 16,
				 ((new_plane_state->src_w & 0xffff) * 15625) >> 10,
				 new_plane_state->src_h >> 16,
				 ((new_plane_state->src_h & 0xffff) * 15625) >> 10,
				 new_plane_state->src_x >> 16,
				 ((new_plane_state->src_x & 0xffff) * 15625) >> 10,
				 new_plane_state->src_y >> 16,
				 ((new_plane_state->src_y & 0xffff) * 15625) >> 10,
				 fb->width, fb->height);
		return -ENOSPC;
	}
Пример #9
0
/**
 * drm_fb_get_bpp_depth - get the bpp/depth values for format
 * @format: pixel format (DRM_FORMAT_*)
 * @depth: storage for the depth value
 * @bpp: storage for the bpp value
 *
 * This only supports RGB formats here for compat with code that doesn't use
 * pixel formats directly yet.
 */
void drm_fb_get_bpp_depth(uint32_t format, unsigned int *depth,
			  int *bpp)
{
	char *format_name;

	switch (format) {
	case DRM_FORMAT_C8:
	case DRM_FORMAT_RGB332:
	case DRM_FORMAT_BGR233:
		*depth = 8;
		*bpp = 8;
		break;
	case DRM_FORMAT_XRGB1555:
	case DRM_FORMAT_XBGR1555:
	case DRM_FORMAT_RGBX5551:
	case DRM_FORMAT_BGRX5551:
	case DRM_FORMAT_ARGB1555:
	case DRM_FORMAT_ABGR1555:
	case DRM_FORMAT_RGBA5551:
	case DRM_FORMAT_BGRA5551:
		*depth = 15;
		*bpp = 16;
		break;
	case DRM_FORMAT_RGB565:
	case DRM_FORMAT_BGR565:
		*depth = 16;
		*bpp = 16;
		break;
	case DRM_FORMAT_RGB888:
	case DRM_FORMAT_BGR888:
		*depth = 24;
		*bpp = 24;
		break;
	case DRM_FORMAT_XRGB8888:
	case DRM_FORMAT_XBGR8888:
	case DRM_FORMAT_RGBX8888:
	case DRM_FORMAT_BGRX8888:
		*depth = 24;
		*bpp = 32;
		break;
	case DRM_FORMAT_XRGB2101010:
	case DRM_FORMAT_XBGR2101010:
	case DRM_FORMAT_RGBX1010102:
	case DRM_FORMAT_BGRX1010102:
	case DRM_FORMAT_ARGB2101010:
	case DRM_FORMAT_ABGR2101010:
	case DRM_FORMAT_RGBA1010102:
	case DRM_FORMAT_BGRA1010102:
		*depth = 30;
		*bpp = 32;
		break;
	case DRM_FORMAT_ARGB8888:
	case DRM_FORMAT_ABGR8888:
	case DRM_FORMAT_RGBA8888:
	case DRM_FORMAT_BGRA8888:
		*depth = 32;
		*bpp = 32;
		break;
	default:
		format_name = drm_get_format_name(format);
		DRM_DEBUG_KMS("unsupported pixel format %s\n", format_name);
		kfree(format_name);
		*depth = 0;
		*bpp = 0;
		break;
	}
}