drivers/gpu/drm/tegra/plane.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/tegra/plane.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/tegra/plane.c
Extension
.c
Size
18178 bytes
Lines
795
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

if (plane->possible_crtcs & drm_crtc_mask(crtc)) {
			struct tegra_dc *dc = to_tegra_dc(crtc);

			if (!dc->soc->supports_sector_layout)
				return false;
		}
	}

	return true;
}

static bool tegra_plane_format_mod_supported(struct drm_plane *plane,
					     uint32_t format,
					     uint64_t modifier)
{
	const struct drm_format_info *info = drm_format_info(format);

	if (modifier == DRM_FORMAT_MOD_LINEAR)
		return true;

	/* check for the sector layout bit */
	if (fourcc_mod_is_vendor(modifier, NVIDIA)) {
		if (modifier & DRM_FORMAT_MOD_NVIDIA_SECTOR_LAYOUT) {
			if (!tegra_plane_supports_sector_layout(plane))
				return false;
		}
	}

	if (info->num_planes == 1)
		return true;

	return false;
}

const struct drm_plane_funcs tegra_plane_funcs = {
	.update_plane = drm_atomic_helper_update_plane,
	.disable_plane = drm_atomic_helper_disable_plane,
	.destroy = tegra_plane_destroy,
	.reset = tegra_plane_reset,
	.atomic_duplicate_state = tegra_plane_atomic_duplicate_state,
	.atomic_destroy_state = tegra_plane_atomic_destroy_state,
	.format_mod_supported = tegra_plane_format_mod_supported,
};

static int tegra_dc_pin(struct tegra_dc *dc, struct tegra_plane_state *state)
{
	unsigned int i;
	int err;

	for (i = 0; i < state->base.fb->format->num_planes; i++) {
		struct tegra_bo *bo = tegra_fb_get_plane(state->base.fb, i);
		struct host1x_bo_mapping *map;

		map = host1x_bo_pin(dc->dev, &bo->base, DMA_TO_DEVICE, &dc->client.cache);
		if (IS_ERR(map)) {
			err = PTR_ERR(map);
			goto unpin;
		}

		if (!dc->client.group) {
			/*
			 * The display controller needs contiguous memory, so
			 * fail if the buffer is discontiguous and we fail to
			 * map its SG table to a single contiguous chunk of
			 * I/O virtual memory.
			 */
			if (map->chunks > 1) {
				err = -EINVAL;
				goto unpin;
			}

			state->iova[i] = map->phys;
		} else {
			state->iova[i] = bo->iova;
		}

		state->map[i] = map;
	}

	return 0;

unpin:
	dev_err(dc->dev, "failed to map plane %u: %d\n", i, err);

	while (i--) {
		host1x_bo_unpin(state->map[i]);
		state->iova[i] = DMA_MAPPING_ERROR;
		state->map[i] = NULL;
	}

Annotation

Implementation Notes