drivers/gpu/drm/drm_atomic_helper.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/drm_atomic_helper.c
Extension
.c
Size
127623 bytes
Lines
4105
Domain
Driver Families
Bucket
drivers/gpu
Inferred role
Driver Families: exported/initcall integration point
Status
integration 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 (new_encoder) {
			if (encoder_mask & drm_encoder_mask(new_encoder)) {
				drm_dbg_atomic(connector->dev,
					       "[ENCODER:%d:%s] on [CONNECTOR:%d:%s] already assigned\n",
					       new_encoder->base.id, new_encoder->name,
					       connector->base.id, connector->name);

				return -EINVAL;
			}

			encoder_mask |= drm_encoder_mask(new_encoder);
		}
	}

	if (!encoder_mask)
		return 0;

	/*
	 * Second loop, iterate over all connectors not part of the state.
	 *
	 * If a conflicting encoder is found and disable_conflicting_encoders
	 * is not set, an error is returned. Userspace can provide a solution
	 * through the atomic ioctl.
	 *
	 * If the flag is set conflicting connectors are removed from the CRTC
	 * and the CRTC is disabled if no encoder is left. This preserves
	 * compatibility with the legacy set_config behavior.
	 */
	drm_connector_list_iter_begin(state->dev, &conn_iter);
	drm_for_each_connector_iter(connector, &conn_iter) {
		struct drm_crtc_state *crtc_state;

		if (drm_atomic_get_new_connector_state(state, connector))
			continue;

		encoder = connector->state->best_encoder;
		if (!encoder || !(encoder_mask & drm_encoder_mask(encoder)))
			continue;

		if (!disable_conflicting_encoders) {
			drm_dbg_atomic(connector->dev,
				       "[ENCODER:%d:%s] in use on [CRTC:%d:%s] by [CONNECTOR:%d:%s]\n",
				       encoder->base.id, encoder->name,
				       connector->state->crtc->base.id,
				       connector->state->crtc->name,
				       connector->base.id, connector->name);
			ret = -EINVAL;
			goto out;
		}

		new_conn_state = drm_atomic_get_connector_state(state, connector);
		if (IS_ERR(new_conn_state)) {
			ret = PTR_ERR(new_conn_state);
			goto out;
		}

		drm_dbg_atomic(connector->dev,
			       "[ENCODER:%d:%s] in use on [CRTC:%d:%s], disabling [CONNECTOR:%d:%s]\n",
			       encoder->base.id, encoder->name,
			       new_conn_state->crtc->base.id, new_conn_state->crtc->name,
			       connector->base.id, connector->name);

		crtc_state = drm_atomic_get_new_crtc_state(state, new_conn_state->crtc);

		ret = drm_atomic_set_crtc_for_connector(new_conn_state, NULL);
		if (ret)
			goto out;

		if (!crtc_state->connector_mask) {
			ret = drm_atomic_set_mode_prop_for_crtc(crtc_state,
								NULL);
			if (ret < 0)
				goto out;

			crtc_state->active = false;
		}
	}
out:
	drm_connector_list_iter_end(&conn_iter);

	return ret;
}

static void
set_best_encoder(struct drm_atomic_commit *state,
		 struct drm_connector_state *conn_state,
		 struct drm_encoder *encoder)
{
	struct drm_crtc_state *crtc_state;
	struct drm_crtc *crtc;

Annotation

Implementation Notes