drivers/gpu/drm/drm_probe_helper.c

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

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/drm_probe_helper.c
Extension
.c
Size
41442 bytes
Lines
1333
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 (*status != MODE_OK) {
			/* No point in continuing for crtc check as this encoder
			 * will not accept the mode anyway. If all encoders
			 * reject the mode then, at exit, ret will not be
			 * MODE_OK. */
			continue;
		}

		bridge = drm_bridge_chain_get_first_bridge(encoder);
		*status = drm_bridge_chain_mode_valid(bridge,
						      &connector->display_info,
						      mode);
		drm_bridge_put(bridge);
		if (*status != MODE_OK) {
			/* There is also no point in continuing for crtc check
			 * here. */
			continue;
		}

		drm_for_each_crtc(crtc, dev) {
			if (!drm_encoder_crtc_ok(encoder, crtc))
				continue;

			*status = drm_crtc_mode_valid(crtc, mode);
			if (*status == MODE_OK) {
				/* If we get to this point there is at least
				 * one combination of encoder+crtc that works
				 * for this mode. Lets return now. */
				return 0;
			}
		}
	}

	return 0;
}

static int drm_helper_probe_add_cmdline_mode(struct drm_connector *connector)
{
	struct drm_cmdline_mode *cmdline_mode;
	struct drm_display_mode *mode;

	cmdline_mode = &connector->cmdline_mode;
	if (!cmdline_mode->specified)
		return 0;

	/* Only add a GTF mode if we find no matching probed modes */
	list_for_each_entry(mode, &connector->probed_modes, head) {
		if (mode->hdisplay != cmdline_mode->xres ||
		    mode->vdisplay != cmdline_mode->yres)
			continue;

		if (cmdline_mode->refresh_specified) {
			/* The probed mode's vrefresh is set until later */
			if (drm_mode_vrefresh(mode) != cmdline_mode->refresh)
				continue;
		}

		/* Mark the matching mode as being preferred by the user */
		mode->type |= DRM_MODE_TYPE_USERDEF;
		return 0;
	}

	mode = drm_mode_create_from_cmdline_mode(connector->dev,
						 cmdline_mode);
	if (mode == NULL)
		return 0;

	drm_mode_probed_add(connector, mode);
	return 1;
}

enum drm_mode_status drm_crtc_mode_valid(struct drm_crtc *crtc,
					 const struct drm_display_mode *mode)
{
	const struct drm_crtc_helper_funcs *crtc_funcs = crtc->helper_private;

	if (!crtc_funcs || !crtc_funcs->mode_valid)
		return MODE_OK;

	return crtc_funcs->mode_valid(crtc, mode);
}

enum drm_mode_status drm_encoder_mode_valid(struct drm_encoder *encoder,
					    const struct drm_display_mode *mode)
{
	const struct drm_encoder_helper_funcs *encoder_funcs =
		encoder->helper_private;

	if (!encoder_funcs || !encoder_funcs->mode_valid)
		return MODE_OK;

Annotation

Implementation Notes