Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5c679994 authored by Eric Anholt's avatar Eric Anholt
Browse files

drm/vc4: Move the plane clipping/scaling setup to a separate function.



As we add actual scaling, this is going to get way more complicated.

Signed-off-by: default avatarEric Anholt <eric@anholt.net>
parent 17eac751
Loading
Loading
Loading
Loading
+52 −26
Original line number Original line Diff line number Diff line
@@ -40,6 +40,14 @@ struct vc4_plane_state {
	 * hardware at vc4_crtc_atomic_flush() time.
	 * hardware at vc4_crtc_atomic_flush() time.
	 */
	 */
	u32 __iomem *hw_dlist;
	u32 __iomem *hw_dlist;

	/* Clipped coordinates of the plane on the display. */
	int crtc_x, crtc_y, crtc_w, crtc_h;

	/* Offset to start scanning out from the start of the plane's
	 * BO.
	 */
	u32 offset;
};
};


static inline struct vc4_plane_state *
static inline struct vc4_plane_state *
@@ -151,22 +159,17 @@ static void vc4_dlist_write(struct vc4_plane_state *vc4_state, u32 val)
	vc4_state->dlist[vc4_state->dlist_count++] = val;
	vc4_state->dlist[vc4_state->dlist_count++] = val;
}
}


/* Writes out a full display list for an active plane to the plane's
static int vc4_plane_setup_clipping_and_scaling(struct drm_plane_state *state)
 * private dlist state.
 */
static int vc4_plane_mode_set(struct drm_plane *plane,
			      struct drm_plane_state *state)
{
{
	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
	struct drm_framebuffer *fb = state->fb;
	struct drm_framebuffer *fb = state->fb;
	struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);

	u32 ctl0_offset = vc4_state->dlist_count;
	vc4_state->offset = fb->offsets[0];
	const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format);

	uint32_t offset = fb->offsets[0];
	vc4_state->crtc_x = state->crtc_x;
	int crtc_x = state->crtc_x;
	vc4_state->crtc_y = state->crtc_y;
	int crtc_y = state->crtc_y;
	vc4_state->crtc_w = state->crtc_w;
	int crtc_w = state->crtc_w;
	vc4_state->crtc_h = state->crtc_h;
	int crtc_h = state->crtc_h;


	if (state->crtc_w << 16 != state->src_w ||
	if (state->crtc_w << 16 != state->src_w ||
	    state->crtc_h << 16 != state->src_h) {
	    state->crtc_h << 16 != state->src_h) {
@@ -178,18 +181,41 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
		return -EINVAL;
		return -EINVAL;
	}
	}


	if (crtc_x < 0) {
	if (vc4_state->crtc_x < 0) {
		offset += drm_format_plane_cpp(fb->pixel_format, 0) * -crtc_x;
		vc4_state->offset += (drm_format_plane_cpp(fb->pixel_format,
		crtc_w += crtc_x;
							   0) *
		crtc_x = 0;
				      -vc4_state->crtc_x);
		vc4_state->crtc_w += vc4_state->crtc_x;
		vc4_state->crtc_x = 0;
	}

	if (vc4_state->crtc_y < 0) {
		vc4_state->offset += fb->pitches[0] * -vc4_state->crtc_y;
		vc4_state->crtc_h += vc4_state->crtc_y;
		vc4_state->crtc_y = 0;
	}
	}


	if (crtc_y < 0) {
	return 0;
		offset += fb->pitches[0] * -crtc_y;
		crtc_h += crtc_y;
		crtc_y = 0;
}
}



/* Writes out a full display list for an active plane to the plane's
 * private dlist state.
 */
static int vc4_plane_mode_set(struct drm_plane *plane,
			      struct drm_plane_state *state)
{
	struct vc4_plane_state *vc4_state = to_vc4_plane_state(state);
	struct drm_framebuffer *fb = state->fb;
	struct drm_gem_cma_object *bo = drm_fb_cma_get_gem_obj(fb, 0);
	u32 ctl0_offset = vc4_state->dlist_count;
	const struct hvs_format *format = vc4_get_hvs_format(fb->pixel_format);
	int ret;

	ret = vc4_plane_setup_clipping_and_scaling(state);
	if (ret)
		return ret;

	vc4_dlist_write(vc4_state,
	vc4_dlist_write(vc4_state,
			SCALER_CTL0_VALID |
			SCALER_CTL0_VALID |
			(format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
			(format->pixel_order << SCALER_CTL0_ORDER_SHIFT) |
@@ -199,8 +225,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
	/* Position Word 0: Image Positions and Alpha Value */
	/* Position Word 0: Image Positions and Alpha Value */
	vc4_dlist_write(vc4_state,
	vc4_dlist_write(vc4_state,
			VC4_SET_FIELD(0xff, SCALER_POS0_FIXED_ALPHA) |
			VC4_SET_FIELD(0xff, SCALER_POS0_FIXED_ALPHA) |
			VC4_SET_FIELD(crtc_x, SCALER_POS0_START_X) |
			VC4_SET_FIELD(vc4_state->crtc_x, SCALER_POS0_START_X) |
			VC4_SET_FIELD(crtc_y, SCALER_POS0_START_Y));
			VC4_SET_FIELD(vc4_state->crtc_y, SCALER_POS0_START_Y));


	/* Position Word 1: Scaled Image Dimensions.
	/* Position Word 1: Scaled Image Dimensions.
	 * Skipped due to SCALER_CTL0_UNITY scaling.
	 * Skipped due to SCALER_CTL0_UNITY scaling.
@@ -212,8 +238,8 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
				      SCALER_POS2_ALPHA_MODE_PIPELINE :
				      SCALER_POS2_ALPHA_MODE_PIPELINE :
				      SCALER_POS2_ALPHA_MODE_FIXED,
				      SCALER_POS2_ALPHA_MODE_FIXED,
				      SCALER_POS2_ALPHA_MODE) |
				      SCALER_POS2_ALPHA_MODE) |
			VC4_SET_FIELD(crtc_w, SCALER_POS2_WIDTH) |
			VC4_SET_FIELD(vc4_state->crtc_w, SCALER_POS2_WIDTH) |
			VC4_SET_FIELD(crtc_h, SCALER_POS2_HEIGHT));
			VC4_SET_FIELD(vc4_state->crtc_h, SCALER_POS2_HEIGHT));


	/* Position Word 3: Context.  Written by the HVS. */
	/* Position Word 3: Context.  Written by the HVS. */
	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
@@ -221,7 +247,7 @@ static int vc4_plane_mode_set(struct drm_plane *plane,
	vc4_state->pw0_offset = vc4_state->dlist_count;
	vc4_state->pw0_offset = vc4_state->dlist_count;


	/* Pointer Word 0: RGB / Y Pointer */
	/* Pointer Word 0: RGB / Y Pointer */
	vc4_dlist_write(vc4_state, bo->paddr + offset);
	vc4_dlist_write(vc4_state, bo->paddr + vc4_state->offset);


	/* Pointer Context Word 0: Written by the HVS */
	/* Pointer Context Word 0: Written by the HVS */
	vc4_dlist_write(vc4_state, 0xc0c0c0c0);
	vc4_dlist_write(vc4_state, 0xc0c0c0c0);