drivers/gpu/drm/i915/display/i9xx_plane.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/i915/display/i9xx_plane.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/i915/display/i9xx_plane.c
Extension
.c
Size
37314 bytes
Lines
1272
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: implementation source
Status
source implementation candidate

Why This File Exists

Repeatable hardware-adapter layer. Deep compatibility for every driver is out of scope; this atlas records patterns, probe lifecycles, bus glue, IRQ/DMA usage, and links back to core abstractions.

Dependency Surface

Detected Declarations

Annotated Snippet

while ((src_x + src_w) * cpp > plane_state->view.color_plane[0].mapping_stride) {
			if (offset == 0) {
				drm_dbg_kms(display->drm,
					    "[PLANE:%d:%s] unable to find suitable display surface offset due to X-tiling\n",
					    plane->base.base.id, plane->base.name);
				return -EINVAL;
			}

			offset = intel_plane_adjust_aligned_offset(&src_x, &src_y, plane_state, 0,
								   offset, offset - alignment);
		}
	}

	/*
	 * Put the final coordinates back so that the src
	 * coordinate checks will see the right values.
	 */
	drm_rect_translate_to(&plane_state->uapi.src,
			      src_x << 16, src_y << 16);

	/* HSW/BDW do this automagically in hardware */
	if (!display->platform.haswell && !display->platform.broadwell) {
		unsigned int rotation = plane_state->hw.rotation;
		int src_w = drm_rect_width(&plane_state->uapi.src) >> 16;
		int src_h = drm_rect_height(&plane_state->uapi.src) >> 16;

		if (rotation & DRM_MODE_ROTATE_180) {
			src_x += src_w - 1;
			src_y += src_h - 1;
		} else if (rotation & DRM_MODE_REFLECT_X) {
			src_x += src_w - 1;
		}
	}

	if (display->platform.haswell || display->platform.broadwell) {
		drm_WARN_ON(display->drm, src_x > 8191 || src_y > 4095);
	} else if (DISPLAY_VER(display) >= 4 &&
		   fb->modifier == I915_FORMAT_MOD_X_TILED) {
		drm_WARN_ON(display->drm, src_x > 4095 || src_y > 4095);
	}

	plane_state->view.color_plane[0].offset = offset;
	plane_state->view.color_plane[0].x = src_x;
	plane_state->view.color_plane[0].y = src_y;

	return 0;
}

static int
i9xx_plane_check(struct intel_crtc_state *crtc_state,
		 struct intel_plane_state *plane_state)
{
	struct intel_plane *plane = to_intel_plane(plane_state->uapi.plane);
	int ret;

	ret = chv_plane_check_rotation(plane_state);
	if (ret)
		return ret;

	ret = intel_plane_check_clipping(plane_state, crtc_state,
					 DRM_PLANE_NO_SCALING,
					 DRM_PLANE_NO_SCALING,
					 i9xx_plane_has_windowing(plane));
	if (ret)
		return ret;

	ret = i9xx_check_plane_surface(plane_state);
	if (ret)
		return ret;

	if (!plane_state->uapi.visible)
		return 0;

	ret = intel_plane_check_src_coordinates(plane_state);
	if (ret)
		return ret;

	plane_state->ctl = i9xx_plane_ctl(plane_state);

	return 0;
}

static u32 i8xx_plane_surf_offset(const struct intel_plane_state *plane_state)
{
	int x = plane_state->view.color_plane[0].x;
	int y = plane_state->view.color_plane[0].y;

	return intel_fb_xy_to_linear(x, y, plane_state, 0);
}

Annotation

Implementation Notes