drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c

Source file repositories/reference/linux-study-clean/drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c

File Facts

System
Linux kernel
Corpus path
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_dp.c
Extension
.c
Size
6485 bytes
Lines
261
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 (dp_dev->hpd_status != HIBMC_HPD_IN) {
			ret = connector_status_disconnected;
			goto exit;
		}
	}

	if (!hibmc_dp_get_dpcd(dp_dev)) {
		ret = connector_status_disconnected;
		goto exit;
	}

	if (!dp_dev->is_branch) {
		ret = connector_status_connected;
		goto exit;
	}

	if (drm_dp_read_sink_count_cap(connector, dp_dev->dpcd, &dp_dev->desc) &&
	    dp_dev->downstream_ports[0] & DP_DS_PORT_HPD) {
		ret = drm_dp_read_sink_count(dp_dev->aux);
		if (ret > 0) {
			ret = connector_status_connected;
			goto exit;
		}
	}

exit:
	dp->phys_status = ret;

	return ret;
}

static int hibmc_dp_mode_valid(struct drm_connector *connector,
			       const struct drm_display_mode *mode,
			       struct drm_modeset_acquire_ctx *ctx,
			       enum drm_mode_status *status)
{
	struct hibmc_dp *dp = to_hibmc_dp(connector);
	u64 cur_val, max_val;

	/* check DP link BW */
	cur_val = (u64)mode->clock * HIBMC_DP_BPP;
	max_val = (u64)hibmc_dp_get_link_rate(dp) * DP_MODE_VALI_CAL * hibmc_dp_get_lanes(dp);

	*status = cur_val > max_val ? MODE_CLOCK_HIGH : MODE_OK;

	return 0;
}

static const struct drm_connector_helper_funcs hibmc_dp_conn_helper_funcs = {
	.get_modes = hibmc_dp_connector_get_modes,
	.detect_ctx = hibmc_dp_detect,
	.mode_valid_ctx = hibmc_dp_mode_valid,
};

static int hibmc_dp_late_register(struct drm_connector *connector)
{
	struct hibmc_dp *dp = to_hibmc_dp(connector);

	hibmc_dp_enable_int(dp);

	return drm_dp_aux_register(&dp->aux);
}

static void hibmc_dp_early_unregister(struct drm_connector *connector)
{
	struct hibmc_dp *dp = to_hibmc_dp(connector);

	drm_dp_aux_unregister(&dp->aux);

	hibmc_dp_disable_int(dp);
}

static const struct drm_connector_funcs hibmc_dp_conn_funcs = {
	.reset = drm_atomic_helper_connector_reset,
	.fill_modes = drm_helper_probe_single_connector_modes,
	.destroy = drm_connector_cleanup,
	.atomic_duplicate_state = drm_atomic_helper_connector_duplicate_state,
	.atomic_destroy_state = drm_atomic_helper_connector_destroy_state,
	.late_register = hibmc_dp_late_register,
	.early_unregister = hibmc_dp_early_unregister,
	.debugfs_init = hibmc_debugfs_init,
};

static inline int hibmc_dp_prepare(struct hibmc_dp *dp, struct drm_display_mode *mode)
{
	int ret;

	hibmc_dp_display_en(dp, false);

	ret = hibmc_dp_mode_set(dp, mode);

Annotation

Implementation Notes